我期待使用exiftool从我的照片和视频扫描EXIF标签。 这是一个Perl的可执行文件。 什么是与此有关inferface最好的方法是什么? 是否有任何Python库已经这样做吗? 或者我应该直接调用可执行文件,并解析输出? (后者似乎很脏。)谢谢。
因为我目前使用pyexiv2,它不具有视频支持,我想问的原因是这样的。 Perl的exiftool对图像和视频的广泛支持,我想使用它。
我期待使用exiftool从我的照片和视频扫描EXIF标签。 这是一个Perl的可执行文件。 什么是与此有关inferface最好的方法是什么? 是否有任何Python库已经这样做吗? 或者我应该直接调用可执行文件,并解析输出? (后者似乎很脏。)谢谢。
因为我目前使用pyexiv2,它不具有视频支持,我想问的原因是这样的。 Perl的exiftool对图像和视频的广泛支持,我想使用它。
为了避免启动一个新的进程为每个图像,你应该开始exiftool
使用-stay_open
标志。 然后,您可以通过标准输入发送命令的过程,并读取标准输出的输出。 ExifTool支持JSON输出,这可能是用于读取元数据的最佳选择。
下面是启动一个简单的类exiftool
工艺,并设有一个execute()
方法将命令发送到该进程。 我还包括get_metadata()
读取JSON格式的元数据:
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)
编辑蟒蛇3:为了得到这个在Python需要3两个小的变化工作。 第一个是一个额外的参数,以subprocess.Popen
:
self.process = subprocess.Popen(
[self.executable, "-stay_open", "True", "-@", "-"],
universal_newlines=True,
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
第二个是,你必须通过返回的字节系列解码os.read()
output += os.read(fd, 4096).decode('utf-8')
编辑窗口:要获得在Windows上工作时, sentinel
需要改变成"{ready}\r\n"
,即
sentinel = "{ready}\r\n"
否则,程序将挂起,因为while循环内的execute()不会停止