12

写真やビデオからEXIFタグをスキャンするためにexiftoolを使用したいと思っています。これはperl実行可能ファイルです。これを推測するための最良の方法は何ですか?これを行うためのPythonライブラリはすでにありますか?または、実行可能ファイルを直接呼び出して出力を解析する必要がありますか?(後者は汚れているようです。)ありがとう。

私が尋ねる理由は、私が現在ビデオをサポートしていないpyexiv2を使用しているためです。Perlのexiftoolは、画像とビデオを非常に幅広くサポートしているので、それを使用したいと思います。

4

2 に答える 2

34

画像ごとに新しいプロセスが起動しないようにするには、フラグexiftoolの使用を開始する必要があります。-stay_open次に、stdinを介してプロセスにコマンドを送信し、stdoutの出力を読み取ることができます。ExifToolはJSON出力をサポートします。これは、メタデータを読み取るためのおそらく最良のオプションです。

これは、プロセスを起動し、そのプロセスにコマンドを送信exiftoolするメソッドを備えた単純なクラスです。また、JSON形式のメタデータを読み取るexecute()ことも含まれています。get_metadata()

import subprocess
import os
import json

class ExifTool(object):

    sentinel = "{ready}\n"

    def __init__(self, executable="/usr/bin/exiftool"):
        self.executable = executable

    def __enter__(self):
        self.process = subprocess.Popen(
            [self.executable, "-stay_open", "True",  "-@", "-"],
            stdin=subprocess.PIPE, stdout=subprocess.PIPE)
        return self

    def  __exit__(self, exc_type, exc_value, traceback):
        self.process.stdin.write("-stay_open\nFalse\n")
        self.process.stdin.flush()

    def execute(self, *args):
        args = args + ("-execute\n",)
        self.process.stdin.write(str.join("\n", args))
        self.process.stdin.flush()
        output = ""
        fd = self.process.stdout.fileno()
        while not output.endswith(self.sentinel):
            output += os.read(fd, 4096)
        return output[:-len(self.sentinel)]

    def get_metadata(self, *filenames):
        return json.loads(self.execute("-G", "-j", "-n", *filenames))

このクラスは、完了した場合にプロセスが確実に終了するように、コンテキストマネージャーとして作成されます。あなたはそれをとして使うことができます

with ExifTool() as e:
    metadata = e.get_metadata(*filenames)

Python 3の編集:これをPython 3で機能させるには、2つの小さな変更が必要です。1つ目は、次の追加の引数subprocess.Popenです。

self.process = subprocess.Popen(
         [self.executable, "-stay_open", "True",  "-@", "-"],
         universal_newlines=True,
         stdin=subprocess.PIPE, stdout=subprocess.PIPE)

os.read()2つ目は、 :によって返されるバイト系列をデコードする必要があることです。

output += os.read(fd, 4096).decode('utf-8')

Windows用の編集:これをWindowsで機能させるには、次のようsentinelに変更する必要があります。"{ready}\r\n"

sentinel = "{ready}\r\n"

そうしないと、execute()内のwhileループが停止しないため、プログラムがハングします。

于 2012-04-09T15:04:24.160 に答える
0

これを参照として使用して..。

import subprocess
import os
import json

class ExifTool(object):

    sentinel = "{ready}\n"

    def __init__(self, executable="/usr/bin/exiftool"):
        self.executable = executable

    def __enter__(self):
        self.process = subprocess.Popen(
            [self.executable, "-stay_open", "True",  "-@", "-"],
            stdin=subprocess.PIPE, stdout=subprocess.PIPE)
        return self

    def  __exit__(self, exc_type, exc_value, traceback):
        self.process.stdin.write("-stay_open\nFalse\n")
        self.process.stdin.flush()

    def execute(self, *args):
        args = args + ("-execute\n",)
        self.process.stdin.write(str.join("\n", args))
        self.process.stdin.flush()
        output = ""
        fd = self.process.stdout.fileno()
        while not output.endswith(self.sentinel):
            output += os.read(fd, 4096)
        return output[:-len(self.sentinel)]

    def get_metadata(self, *filenames):
        return json.loads(self.execute("-G", "-j", "-n", *filenames))

...Python3.8.10とIPYTHONを使用してFollowERRORを返します。

"AttributeError Traceback(最後の最後の呼び出し)56 57 e = ExifTool()---> 58 e.load_metadata_lookup('/ u02 / RECOVERY /')

in load_metadata_lookup(self、locDir)51'\ n FILELOC>'、FileLoc、'\ n')52 ---> 53 self.get_metadata(FileLoc)54 55

in get_metadata(self、FileLoc)38 39 def get_metadata(self、FileLoc):---> 40 return json.loads(self.execute( "-G"、 "-j"、 "-n"、FileLoc))41 42

in execute(self、* args)28 def execute(self、* args):29 args = args +( "-execute \ n"、)---> 30 self.process.stdin.write(str.join( " \ n "、args))31 self.process.stdin.flush()32 output =" "

AttributeError:'ExifTool'オブジェクトに属性'process'がありません

..。

その後、いくつかの変更を加えて...成功!!! ...[https://stackoverflow.com/users/279627/sven-marnach]を使用して変更および適応

#!/usr/local/bin/python3
#! -*- coding: utf-8-mb4 -*-
from __future__ import absolute_import

import sys
import os
import subprocess
import json

headers_infos = """
.:.
.:. box33 | systems | platform |
.:. [   Renan Moura     ]
.:. [   ver.: 9.1.2-b   ]
.:.
"""

class ExifTool(object):
    sentinel = "{ready}\n"
    def __init__(self):
        self.executable         = "/usr/bin/exiftool"
        self.metadata_lookup    = {}

    def  __exit__(self, exc_type, exc_value, traceback):
        self.process.stdin.write("-stay_open\nFalse\n")
        self.process.stdin.flush()

    def execute(self, *args):
        self.process = subprocess.Popen([self.executable, "-stay_open", "True",  "-@", "-"],
            universal_newlines  = True                          ,
            stdin               = subprocess.PIPE               ,
            stdout              = subprocess.PIPE               ,
            stderr              = subprocess.STDOUT
        )

        args = (args + ("-execute\n",))

        self.process.stdin.write(str.join("\n", args))
        self.process.stdin.flush()

        output  = ""
        fd      = self.process.stdout.fileno()

        while not output.endswith(self.sentinel):
            output += os.read(fd, 4096).decode('utf-8')

        return output[:-len(self.sentinel)]

    def get_metadata(self, *FileLoc):
        return json.loads(self.execute("-G", "-j", "-n", *FileLoc))

    def load_metadata_lookup(self, locDir):
        self.metadata_lookup = {}
        for dirname, dirnames, filenames in os.walk(locDir):
            for filename in filenames:
                FileLoc=(dirname + '/' + filename)
                print(  '\n FILENAME    > ', filename,
                        '\n DIRNAMES    > ', dirnames,
                        '\n DIRNAME     > ', dirname,
                        '\n FILELOC     > ', FileLoc, '\n')

                self.metadata_lookup = self.get_metadata(FileLoc)
                print(json.dumps(self.metadata_lookup, indent=3))

e = ExifTool()
e.load_metadata_lookup('/u02/RECOVERY/')

...「/u02/ RECOVERY/」からのこのコードllに注意してください...ディレクトリが見つかり、見つかったすべてのドキュメントで実行されます...これがuに役立つことを願っています...

于 2021-11-12T02:20:32.313 に答える