Reputation: 1434
I would like to preserve the creation time metadata when I convert videos using ffmpeg/avconv. Here is the file I'm trying to convert:
$ ffmpeg -i in.avi
ffmpeg version 0.8.6-4:0.8.6-0ubuntu0.12.04.1, Copyright (c) 2000-2013 the Libav developers
built on Apr 2 2013 17:00:59 with gcc 4.6.3
Input #0, avi, from 'in.avi':
Metadata:
creation_time : 2013-08-12 06:59:14
encoder : CanonMVI06
Duration: 00:00:12.26, start: 0.000000, bitrate: 14549 kb/s
Stream #0.0: Video: mjpeg, yuvj422p, 640x480, 30 tbr, 30 tbn, 30 tbc
Stream #0.1: Audio: pcm_u8, 11024 Hz, 1 channels, u8, 88 kb/s
In the first approach I run
$ ffmpeg -i in.avi -vcodec libx264 -acodec libmp3lame -r 30 -map_metadata 0 out.avi
and get an output file which doesn't have the 'creation_date' metadata that I'd like to keep:
$ ffmpeg -i out.avi
ffmpeg version 0.8.6-4:0.8.6-0ubuntu0.12.04.1, Copyright (c) 2000-2013 the Libav developers
built on Apr 2 2013 17:00:59 with gcc 4.6.3
[avi @ 0x83ba260] max_analyze_duration reached
Input #0, avi, from 'out.avi':
Metadata:
encoder : Lavf53.21.1
Duration: 00:00:12.38, start: 0.000000, bitrate: 704 kb/s
Stream #0.0: Video: h264 (Main), yuv420p, 640x480, 30 fps, 30 tbr, 30 tbn, 60 tbc
Stream #0.1: Audio: mp3, 11025 Hz, mono, s16, 200 kb/s
I also tried another approach
$ ffmpeg -i in.avi -f ffmetadata metadata.txt
$ ffmpeg -i in.avi -f ffmetadata -i metadata.txt -vcodec libx264 -acodec libmp3lame -r 30 out.avi
with the same success even though metadata.txt has the right info:
;FFMETADATA1
creation_time=2013-08-12 06:59:14
encoder=CanonMVI06
What am I doing wrong?
Upvotes: 3
Views: 4926
Reputation: 3043
To keep both the common creation date (touch) and metadata creation date:
#! /bin/bash
shopt -s globstar || exit
for f in **
do
if [[ "$f" =~ \.AVI$ ]] || [[ "$f" =~ \.avi$ ]] ; then
t="${f%.*}"_compressed.mp4
tM="${f%.*}"_compressedM.mp4
txt="${f%.*}".txt
ffmpeg -i "$f" -c copy -map_metadata 0 -map_metadata:s:v 0:s:v -map_metadata:s:a 0:s:a -f ffmetadata "$txt"
if yes | ffmpeg -i "$f" -c:v libx264 -crf 20 -c:a aac -strict -2 "$t"; then
ffmpeg -i "$t" -f ffmetadata -i "$txt" -c copy -map_metadata 1 "$tM"
touch -r "$f" "$tM"
rm -f "$t"
else
rm -f "$t"
echo "Command failed"
fi
fi
done
Upvotes: 3
Reputation: 1434
The approach I ended up taking is to bake the timestamp into the filename as well as to adjust the "last modified" timestamp on the compressed video file. Here's the script I use to batch convert my videos:
#!/bin/bash
mkdir -p compressed
for f in *.MP4; do
avconv -i "$f" -vcodec libx264 -s 1366x768 -crf 26 -acodec libmp3lame -map_metadata 0 "compressed/${f%.*}.mp4"
touch -r "$f" "compressed/${f%.*}.mp4" # adjust the timestamp
time=$(date -r ${f} +%Y%m%d)
mv "compressed/${f%.*}.mp4" "compressed/${time}_${f%.*}.mp4" # add timestamp to the file name
done
Most videos from modern mobile devices already have timestamps in the file name, so you may want to skip that step
Upvotes: 0