从多个视频中提取元数据
我面临的挑战需要bash的多个方面。我在Linux上工作(正是Debian Stretch)。这里的情况(所有点/问题,我沿着我认为对于现在的解决办法写,但我接受其他的想法):从多个视频中提取元数据
我有多种类型(以及各种上下案例视频),如.mp4,.mov,.MOV,.MP4,.avi,...位于一个目录中(并遍布在一个几乎没有结构的目录树中)。为了找到所有我试图使用
find
命令对于每个视频,我需要提取一些元数据(即文件的名称,视频的持续时间,文件大小和创建日期/上次修改)。包
mediainfo
产生(在很多其他事情中)所需的字段。mediainfo
的输出格式为:<Tag>\t : <value>
。我需要提取字段的值完整名称,持续时间,文件大小和编码日期。因此,所有这些信息,我必须过滤所需的字段值,并把它们放入一个CSV文件。我考虑使用
sed
。
我的目标是通过脚本或少量单独的命令实现所有这些任务。
的想法代码(这个代码是令人发指的错,但你可以得到一个想法):
find . -type f -name "*.[mp4|MP4|mov|MOV|avi|AVI]" -exec mediainfo {} | sed '/Complete name|Duration|File size|Encoded date/p' > myfile.csv \;
请问您有什么想法如何执行这项任务?我觉得结合发现,执行和sed和输出到csv感到非常失落...
在此先感谢您的帮助!
所以我终于设法编写了一个脚本。可能不是最好的办法,但在这里它是:
resFile="myresult.csv"
dstDir="./destination/"
srcDir="./source/"
#first copy all files at same level in dstDir (with preserve and update)
#this is somehow necessary, relative name for MOV files and mediainfo
#do not seem to work together.
find $srcDir -type f \(-name "*.mp4" -o -name "*.mov" -o -name "*.MOV" -o -name "*.avi" \) -exec cp -up {} $dstDir \;
#then for each file, output mediainfo of file and keep only interesting tags. add ### between each file.
find $dstDir -type f \(-name "*.mp4" -o -name "*.mov" -o -name "*.MOV" -o -name "*.avi"\
-exec sh -c " mediainfo --Output=XML {} | sed '1,15!d;/Duration\|Complete\|File_size\|Encoded_date/!d' >> $resFile && echo '########' >> $resFile" \;
#removes tags : <Duration>42s 15ms</Duration> -> 42s 15ms
sed -i 's/^<.*>\(.*\)<.*>/\1/I' $resFile
#Extract exact filename (and not relative)
sed -i 's/^\.\/.*\/\(.*\)\.[mp4|MOV|mov|avi|MP4]/\1/' $resFile
#Puts fields for a file on a unique line separated with commas
sed -i 'N;s/\n/,/;N;s/\n/,/;N;s/\n/,/;N;s/\n/,/' $resFile
#remove all trailing ###
sed -i 's/,#*$//' $resFile
我仍然有兴趣,如果任何人有想法,以改善代码。 我“最小化”了一点,我的实际代码是一个更模块化,并执行一些检查
试试这个。由于时间较少,我无法完成。您只需将输出发送到CSV。
for c in $(locate --basename .mp4 .mkv .wmv .flv .webm .mov .avi)
do
Complete_name=$(mediainfo --Output=XML $c | xml_grep 'Complete_name' --text_only| awk 'BEGIN{FS="/"}{print $NF}')
echo $Complete_name
Duration=$(mediainfo --Output=XML $c | xml_grep 'Duration' --text_only --nb_result 1)
echo $Duration
File_size=$(mediainfo --Output=XML $c | xml_grep 'File_size' --text_only)
echo $File_size
Encoded_date=$(mediainfo --Output=XML $c | xml_grep 'Encoded_date' --text_only -nb_result 1 | awk '{print $2}')
echo $Encoded_date
done
看起来不错。我需要一些时间来深入了解并修正一些细节,但看起来效率很高。谢谢。 – Battleman
你知道吗,那个'mediainfo' [有](http://manpages.ubuntu.com/manpages/precise/man1/mediainfo.1.html)'--output = XML'参数?也许这会更容易解析XML甚至使用它而不是CSV?为了使用xml,你可以使用[xmllint](http://xmlsoft.org/xmllint.html)。 – grundic
不知道,它可能确实更容易解析。谢谢。 – Battleman