Converting video formats and copying tags with ffmpeg
Asked Answered
D

3

16

I've been trying to convert some videos I took on my camera to a compressed format in order to save some storage space. I figured out how to use ffmpeg to convert the videos to the format I want, but what I haven't been able to figure out is how to copy the metadata. I'd like to copy the original metadata from when the video was taken (most importantly the creation time). I've tried running ffmpeg using the -map_meta_data 0:0 option, but that didn't seem to work. Any ideas?

It looks like the data I want to copy in this case is in the format section of the video. Using ffprobe with the show_format option, I get this output:

[FORMAT]
filename=video.AVI
nb_streams=2
format_name=avi
format_long_name=AVI format
start_time=0.000000
duration=124.565421
size=237722700
bit_rate=15267331
TAG:creation_time=2012-02-07 12:15:27
TAG:encoder=CanonMVI06
[/FORMAT]

I would like to copy the two tags to my new video.

Demantoid answered 29/7, 2012 at 1:59 Comment(0)
M
12

Have a look at the documentation on dumping and loading metadata:

FFmpeg is able to dump metadata from media files into a simple UTF-8-encoded INI-like text file and then load it back using the metadata muxer/demuxer.

The process might look something like this:

# First extract metadata
ffmpeg -i original.mov -f ffmetadata metadata.txt
# Next, transcode, including extracted metadata
ffmpeg -i original.mov -f ffmetadata -i metadata.txt compressed.mp4

I don't have a metadata-ful video to test with right now, but something like that should work.

Mendelevium answered 29/7, 2012 at 4:35 Comment(4)
That seems like it should work, but when I extract the metadata the creation_time tag isn't extracted. This is all that is saved to the file, which could also explain why the map_meta_data option wasn't working: ;FFMETADATA1 encoder=CanonMVI06Demantoid
@Demantoid Indeed it might. Though it's completely inelegant and shouldn't be necessary, have tried using ffprobe and grep to get the creation time and then setting it directly in the output using -metadata?Mendelevium
This still didn't quite work, but it pointed me in the right direction. I finally noticed a message getting output when I ran the ffmpeg command that said stfptime was not available (I've been trying to do this on Windows). It turns out that since that library wasn't available on Windows, the date never got placed into the metadata. So, I tried converting my videos in Linux where stfptime is available, and both the map_metadata and the ffmetadata options worked for saving the creation_time tag into the video metadata.Demantoid
The last command won't work. Because you did not tell the ffmpeg which metadata it should choose. you need to use -map_metadata 1 to select the 2nd input as metadata.Wray
B
11

Use "-map_metadata 0:g" to copy all global metadata.

0 means Input #0. g means global metadata.

Here's my ffprobe result. enjoy!

input.mp4

[FORMAT]
filename=input.mp4
nb_streams=2
nb_programs=0
format_name=mov,mp4,m4a,3gp,3g2,mj2
format_long_name=QuickTime / MOV
start_time=0.000000
duration=60.560500
size=190252680
bit_rate=25132246
probe_score=100
TAG:major_brand=mp42
TAG:minor_version=1
TAG:compatible_brands=mp42avc1
TAG:creation_time=2016-05-14 10:01:17
[/FORMAT]

output.mp4

[FORMAT]
filename=output.mp4
nb_streams=2
nb_programs=0
format_name=mov,mp4,m4a,3gp,3g2,mj2
format_long_name=QuickTime / MOV
start_time=0.000000
duration=60.632000
size=38636429
bit_rate=5097826
probe_score=100
TAG:major_brand=isom
TAG:minor_version=512
TAG:compatible_brands=isomiso2avc1mp41
TAG:creation_time=2016-05-14 01:01:17
TAG:encoder=Lavf57.36.100
[/FORMAT]
Blacklist answered 21/5, 2016 at 8:25 Comment(0)
P
10

To write all metadata (global, video, audio) to a file use

ffmpeg -i in.mp4 -c copy -map_metadata 0 -map_metadata:s:v 0:s:v -map_metadata:s:a 0:s:a -f ffmetadata in.txt

To add all metadata from a file use

ffmpeg -i in.mp4 -f ffmetadata -i in.txt -c copy -map_metadata 1 out.mp4
Petrillo answered 29/5, 2018 at 8:57 Comment(7)
I'm trying this and it reencodes the whole file--is that expected? Is there a switch to perhaps only insert the metadata? Btw, what I want is to read the video info (frame height, width, rate, etc), with ffmpeg or ffprobe, and save that to the video file metadata.Allheal
No,reencoding its not expected. -c copy should copy.Petrillo
I don't know if it's reencoding, tbh, but what I see is it crawling through the whole video, minute by minute. Is that what -c copy is supposed to do? Btw, I found out my problem wasn't that the metadata was lacking on the files, but that Windows doesn't natively read metadata from mkv files in its file system, as it does with mp4. Shark007 codecs fixed that (and possibly afforded me other problems).Allheal
Is there a way to only copy the metadata without copying the whole file? I'm looking to copy the metadata to a different file with changed speed and volume.Nightrider
Not correct according to my testing. To export much but not all global data (esp missing creation_time): ffmpeg -i in.mp4 -f ffmetadata meta.txt. To export all global data: ffmpeg -i in.mp4 -map_metadata 0 -f ffmetadata meta.txt. Note: global encoder always gets updated. To export all metadata: ffmpeg -t 0 -i in.mp4 -c copy -map 0 -map_metadata 0 -f ffmetadata meta.txt. Note the added -map 0. The -t 0 saves time (if all data is up front). Doing something like -map_metadata:s:v 0:s:v just messes with things by mapping data from the first video stream to all video streams.Deuteronomy
@Deuteronomy this would make a good answer, rather than a comment. If you repost as an answer, and especially if you expand on the -t 0 switch "saving time", I would push for this to be accepted as the answer.Sutra
@Sutra : I might if I could remember why I didn't do that in the first place. It might have something to do with this exporting to txt when that export step is not always needed. stegoma's 2016 answer looks correct for the specific case here, assuming they ran: ffmpeg -i in.mp4 -c copy -map_metadata 0:g out.mp4 (the :g default is optional). ---- Anyhow, now's a good time to point out that my last sentence above re :s:v is written backwards from what I meant (it maps from all to first, overwriting data in cases of more than one vid stream). -t 0 just prevents a full -c copy scan.Deuteronomy

© 2022 - 2024 — McMap. All rights reserved.