How to change metadata with ffmpeg/avconv without creating a new file?
Asked Answered
P

8

42

I am writing a python script for producing audio and video podcasts. There are a bunch of recorded media files (audio and video) and text files containing the meta information.

Now I want to program a function which shall add the information from the meta data text files to all media files (the original and the converted ones). Because I have to handle many different file formats (wav, flac, mp3, mp4, ogg, ogv...) it would be great to have a tool which add meta data to arbitrary formats.

My Question:

How can I change the metadata of a file with ffmpeg/avconv without changing the audio or video of it and without creating a new file? Is there another commandline/python tool which would do the job for me?

What I tried so far:

I thought ffmpeg/avconv could be such a tool, because it can handle nearly all media formats. I hoped, that if I set -i input_file and the output_file to the same file, ffmpeg/avconv will be smart enough to leave the file unchanged. Then I could set -metadata key=value and just the metadata will be changed.

But I noticed, that if I type avconv -i test.mp3 -metadata title='Test title' test.mp3 the audio test.mp3 will be reconverted in another bitrate.

So I thought to use -c copy to copy all video and audio information. Unfortunately also this does not work:

:~$ du -h test.wav # test.wav is 303 MB big
303M    test.wav

:~$ avconv -i test.wav -c copy -metadata title='Test title' test.wav
avconv version 0.8.3-4:0.8.3-0ubuntu0.12.04.1, Copyright (c) 2000-2012 the
Libav    developers
built on Jun 12 2012 16:37:58 with gcc 4.6.3
[wav @ 0x846b260] max_analyze_duration reached
Input #0, wav, from 'test.wav':
Duration: 00:29:58.74, bitrate: 1411 kb/s
    Stream #0.0: Audio: pcm_s16le, 44100 Hz, 2 channels, s16, 1411 kb/s
File 'test.wav' already exists. Overwrite ? [y/N] y
Output #0, wav, to 'test.wav':
Metadata:
    title           : Test title
    encoder         : Lavf53.21.0
    Stream #0.0: Audio: pcm_s16le, 44100 Hz, 2 channels, 1411 kb/s
Stream mapping:
Stream #0:0 -> #0:0 (copy)
Press ctrl-c to stop encoding
size=     896kB time=5.20 bitrate=1411.3kbits/s    
video:0kB audio:896kB global headers:0kB muxing overhead 0.005014%

:~$ du -h test.wav # file size of test.wav changed dramatically
900K    test.wav

You see, that I cannot use -c copy if input_file and output_file are the same. Of course I could produce a temporarily file:

:-$ avconv -i test.wav -c copy -metadata title='Test title' test_temp.mp3
:-$ mv test_tmp.mp3 test.mp3

But this solution would create (temporarily) a new file on the filesystem and is therefore not preferable.

Propagandize answered 13/7, 2012 at 16:28 Comment(0)
P
29

I asked on the mailing list of avconv and got the following answer:

„No, it's not possible [to change the metadata without creating a new file], neither libavformat API nor avconv design allows for in-place editing of files.“

Propagandize answered 15/7, 2012 at 13:50 Comment(4)
@NikosBaxevanis Most likely by outputting to a temporary file, deleting the original, then renaming the new one. Overwriting a file as you're reading it can cause many problems. For example, ffmpeg will destroy your video file if you do ffmpeg -i video.mkv -c:a copy -c:v copy video.mkvFormative
@ColeJohnson That's probably what it does, and it does it really well! It's interesting to me, because even if you're playing a media file, you can change its ID3 tag on-the-fly! Not sure if/how it does it by copying in the background, but Winamp does it really well!Mucin
The (original) ID3 metadata format in MP3 files is a fixed-size data structure at the end of the file. This makes in-place editing trivial. On the other hand, the newer ID3v2 is a variable-length structure at the beginning of the file (to support streaming) so this often can't be edited in-place.Jaquelin
And there are other audio and video formats. Some do not append data at the end of the file (it is included elsewhere in the file). Some formats are quick and easy to modify the metadata, and others take longer due to how the data has be re-written.Selfdrive
H
61

Note: this answer was given before the question was edited to include a requirement to not create a new file.

Can you edit metadata in-place without creating a new file: no.
Can you edit metadata without changing/re-encoding the audio+visual streams: see below.


You can do this with FFmpeg like so:

ffmpeg -i input.avi -metadata key=value -codec copy output.avi

Example:

$ du -h test.mov 
 27M    test.mov
$ ffprobe -loglevel quiet -show_format out.mov | grep title    # nothing found
$ ffmpeg -loglevel quiet -i test.mov -codec copy -metadata title="My title" out.mov
$ du -h out.mov
 27M    out.mov
$ ffprobe -loglevel quiet -show_format out.mov | grep title
TAG:title=My title

See the documentation for -metadata and on stream copying for more information.

Note also that not all formats allow setting arbitrary metadata, for, e.g., Quicktime doing -metadata title="my title" does what you'd expect, but -metadata foo=bux does nothing.

Hamford answered 13/7, 2012 at 22:15 Comment(5)
In your solution you create a new file. Is there also a way without creating a new file?Propagandize
To clarify a bit, ffmpeg requires an output file to be created. You have an input file, and ffmpeg does not allow direct manipulation of the input file. I believe this practice is due to how large many multimedia files are, since dynamically altering the input file would require caching the entire file. Related to the latter concept, note that ffmpeg does not perform any sanity checks on the input file.Selfdrive
After a bit of trial and error myself, I would recommend ExifTool (exiftool.org) and not FFmpeg for changing metadata. It's easy to use, faster and has option for overwriting the original file.Novick
Problem with exiftool is it does not allow to edit the metadata of streams, only general metadata of the file.Grippe
exiftool doesn't support AVI or MKV, ffmpeg can't change metadata in place, is there anything better?Sepal
P
29

I asked on the mailing list of avconv and got the following answer:

„No, it's not possible [to change the metadata without creating a new file], neither libavformat API nor avconv design allows for in-place editing of files.“

Propagandize answered 15/7, 2012 at 13:50 Comment(4)
@NikosBaxevanis Most likely by outputting to a temporary file, deleting the original, then renaming the new one. Overwriting a file as you're reading it can cause many problems. For example, ffmpeg will destroy your video file if you do ffmpeg -i video.mkv -c:a copy -c:v copy video.mkvFormative
@ColeJohnson That's probably what it does, and it does it really well! It's interesting to me, because even if you're playing a media file, you can change its ID3 tag on-the-fly! Not sure if/how it does it by copying in the background, but Winamp does it really well!Mucin
The (original) ID3 metadata format in MP3 files is a fixed-size data structure at the end of the file. This makes in-place editing trivial. On the other hand, the newer ID3v2 is a variable-length structure at the beginning of the file (to support streaming) so this often can't be edited in-place.Jaquelin
And there are other audio and video formats. Some do not append data at the end of the file (it is included elsewhere in the file). Some formats are quick and easy to modify the metadata, and others take longer due to how the data has be re-written.Selfdrive
C
8

You can also make something like this that deletes the file on success and rename the output

ffmpeg -i default.mp4 -metadata title="my title" -codec copy output.mp4 && mv output.mp4 default.mp4
Cymbal answered 21/8, 2020 at 14:35 Comment(1)
ffmpeg -i default.mp4 -metadata title="my title" -codec copy output.mp4 && mv output.mp4 default.mp4 should work as wellPropagandize
G
6

With ffmpeg, you will always have to copy to a new file. But it has the advantage that it can handle many different formats.

The alternative, without copying the whole file, depends on the format. For many, there are tools wich will allow you to edit metadata "in-place".

  • exiftool for many formats
  • metaflac for FLAC
  • MP4Box for .mp4
  • eyeD3, mid3v2, etc. for MP3
  • etc.

So you would really have to check for what works for you for each specific file format.

Giacomo answered 26/7, 2020 at 17:20 Comment(3)
This is the right answer. OP is asking an XY problemExifTool is the right tool for updating metadata. It comes with a command line tool and perl library. Since OP wants to incorporate this into python, they may want to look at PyExifToolFloury
Do note that exiftool does not support writing metadata for many common music formats like MP3, OGG, FLAC, WAV.Garment
no reason to believe that metadata is the same as stream metadataBastard
C
5

Since changing the metadata will change the length of the file, and I expect the metadata is near the beginning of the file, the audio and video would start at a different offset from the beginning of the file. So you cannot alter the metadata without first creating a temporary file, then renaming files after.

If the new metadata were exactly the same size, and you know where the metadata was located in the container (file) you might be able to use a hex editor of some kind to simply replace characters. Good luck with that.

Also. you might be able to put shorter data in place directly if you paded with nulls, but this might be problematic for some players.

Croton answered 8/4, 2018 at 22:19 Comment(1)
The inconsistencies you mention between old/new file versions are why programs such as VLC often report incorrect track length in music files if the file's artwork tag has been edited, though the content will play correctly.Selfdrive
D
0

This depends on the physical location of the metadata in the file. If the data is at the head of the file, you might be able to 'slice' that section off and edit the data then 'splice' the sections back together. This would only be useful if you had a lot of files to do in a batch. If only one is to be edited, use one of the two-copy methods.

Dubose answered 22/1, 2022 at 4:31 Comment(1)
This is true but is does not answer my question. Thanks anyway for it :-)Propagandize
B
0

Sorry to revive this conversation, but apparently there was no conclusive answer...

I'm looking for something similar, I need to change the metadata of MP4 video files so that they are displayed correctly in the players, but I would like to do this without generating a new file, just editing the metadata of the original file.

I am currently using this ExifTool command line:

exiftool -m -P -overwrite_original -api LargeFileSupport=1 -rotation=90 movie.mp4

But as can be seen here, ExifTool also recreates the files.

The reason

Writing entire files over again on a routine basis will put too much strain on the lifespan of my storage drives.

Bhutan answered 1/1 at 20:27 Comment(0)
A
-1

If like me you have a lot of files with long name (and spaces) to rename, you can save file name and title as variable before and execute always same ffmpeg command after:

input="My default video.mp4" && title="My title video"
ffmpeg -i "$input" -metadata title="$title" -codec copy output.mp4 && mv output.mp4 "$input"

If you have ffmpeg < v.3.2, you can prevent Codec for stream 0 does not use global headers but container format requires global headers warning by adding -flags +global_header flag:

ffmpeg -i "$input" -metadata title="$title" -codec copy -flags +global_header output.mp4 && mv output.mp4 "$input"

Note: I also have to change rights to retrieve same file as before (sudo may be needed):

chmod 774 "$input" && chown admin:users "$input"
Astred answered 20/12, 2020 at 18:22 Comment(1)
Sorry, but you do not answer my question. I was asking to change the metadata without creating a new file..Propagandize

© 2022 - 2024 — McMap. All rights reserved.