IPB

Welcome Guest ( Log In | Register )

 
Reply to this topicStart new topic
ffmpeg: Copy tag from audio file to AAC pre-encoded file
haigoyamakun
post Apr 25 2012, 22:34
Post #1





Group: Banned
Posts: 1
Joined: 25-April 12
Member No.: 99208



I am using neroAacEnc to encode my music, using FFMPEG and pipe conections i connect the ffmpeg output to the neroaacenc input.
ffmpeg -i "somefile"."somecontainer" -acodec pcm_s16le -f wav - | neroaacenc "Some encode options" -ignorelength -if - -of "My new aac file.m4a"

The problem is: The output file does not keep the meta-tags of the input.

But, when ffmpeg decodes the audio to wav, it shows the meta-tags.

Here is my example.

CODE
C:\Users\lucman\Desktop\FFtoACC\bin>ffmpeg.exe -i flac.flac -acodec pcm_s16le -f
wav - | neroaacenc -lc -br 80000 -ignorelength -if - -of aac.m4a
*************************************************************
* *
* Nero AAC Encoder *
* Copyright 2009 Nero AG *
* All Rights Reserved Worldwide *
* *
* Package build date: Feb 18 2010 *
ffmpeg version N-38632-g4cda8aa* Package version: 1.5.4.0
*
Copyright 2000-2012 the FFmpeg developers
built on Mar 8 2012 02:38:08 with gcc 4.5.0 20100414 (Fedora MinGW 4.5.0-1.fc
14)
configuration: --prefix=/var/www/users/research/ffmpeg/snapshots/build --arch=
x86 --target-os=mingw32 --cross-prefix=i686-pc-mingw32- --cc='ccache i686-pc-min
gw32-gcc' --enable-w32threads --enable-memalign-hack --enable-runtime-cpudetect
--enable-cross-compile --enable-static --disable-shared --extra-libs='-lws2_32 -
lwinmm' --extra-cflags='--static -I/var/www/users/research/ffmpeg/snapshots/buil
d/include' --extra-ldflags='-static -L/var/www/users/research/ffmpeg/snapshots/b
uild/lib' --enable-bzlib --enable-zlib --enable-gpl --enable-version3 --enable-n
onfree --enable-libx264 --enable-libspeex --enable-libtheora --enable-libvorbis
--enable-libfaac --enable-libxvid --enable-libopencore-amrnb --enable-libopencor
e-amrwb --enable-libmp3lame --enable-libvpx --disable-decoder=libvpx
* *
libavutil 51. 42.100 / 51. 42.100
* See -help for a complete list of available parameters. *
* *
libavcodec 54. 10.100 / 54. 10.100
*************************************************************

libavformat 54. 2.100 / 54. 2.100
libavdevice 53. 4.100 / 53. 4.100
libavfilter 2. 63.100 / 2. 63.100
libswscale 2. 1.100 / 2. 1.100
libswresample 0. 7.100 / 0. 7.100
libpostproc 52. 0.100 / 52. 0.100
[flac @ 0x378fc0] max_analyze_duration 5000000 reached at 5015510
Input #0, flac, from 'flac.flac':
Metadata:
ARTIST : the GazettE
TITLE : THE INVISIBLE WALL
track : 02
ALBUM : DIM
Duration: 00:04:33.40, bitrate: 1038 kb/s
Stream #0:0: Audio: flac, 44100 Hz, stereo, s16
Output #0, wav, to 'pipe:':
Metadata:
ARTIST : the GazettE
TITLE : THE INVISIBLE WALL
track : 02
ALBUM : DIM
encoder : Lavf54.2.100
Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, stereo, s16
, 1411 kb/s
Stream mapping:
Stream #0:0 -> #0:0 (flac -> pcm_s16le)
Press [q] to stop, [?] for help
size= 47097kB time=00:04:33.40 bitrate=1411.2kbits/s
video:0kB audio:47097kB global headers:0kB muxing overhead 0.000095%


C:\Users\lucman\Desktop\FFtoACC\bin>

Can I copy tag information from one file to another using ffmpeg ??
Something like:
ffmpeg -y -i original-song.flac -copy-metadata my-preencoded-aac.m4a

Also i tried with "TAG.exe" but it can not tag AAC files. sad.gif

I know i can do with Graphical programs, but i need a command-line program, because i'm codding a Bat file generator to Convert FFMPEG to NeroAAC.

Help please.

This post has been edited by db1989: Apr 25 2012, 23:19
Reason for edit: changing enclosure of large log from [quote] to [codebox]
Go to the top of the page
+Quote Post
Takla
post Apr 26 2012, 07:46
Post #2





Group: Members
Posts: 169
Joined: 14-November 09
Member No.: 74931



I'd suggest not using ffmpeg for mapping metadata in this case as it has a couple of drawbacks: ffmpeg can accept multiple input files and then, by using "-map" or "-map_metadata", either ignore or use (convert or copy) streams/metadata from each input file, writing the desired ones to output while discarding the others, but it can't add metadata into an pre-existing file as it always needs to write (or overwrite) to a file (or standard out). Another limitation is that not all audio containers handle metadata and audio streams in the same way, so you'd need to know in advance which stream is which and perhaps if the metadata is read by ffmpeg before or after the audio, which is all too impractical. It's easy enough to write a script which encodes from flac to a temporary m4a (piping ffmpeg wav to neroAacEnc), and then combines the original metadata with the new aac by writing them to yet another new file and then deletes the temp file. But it's clumsy, relatively slow, and while it works with flac or mp3 sources it fails with ogg vorbis. I didn't try with musepack, wavpack, wma or other source audio.

Fortunately there are cross platform command line tools which can read metadata from any kind of multimedia and present it in a standardized form which is easily manipulated. I use mediainfo for this.

And a better approach for the tagging itself is to use neroAacTag because it can insert metadata into an existing file, so no need for temp files.

This bash script does what you're looking for, both encoding from any source and adding the tags to the output, but it's for GNU/Linux, Mac OS X, BSD etc. and not for Windows. However all the same tools are available for Windows so it should be possible to adapt it for a Windows bat (sed can be used in place of the bash parameter substitutions).


CODE
#!/bin/bash

for i in "$@"; do

ARTIST=$(mediainfo "$i" |grep "Performer " | awk -F ': ' '{print $2}')
TITLE=$(mediainfo "$i" |grep "Track name " | awk -F ': ' '{print $2}')
ALBUM=$(mediainfo "$i" |grep "Album " | awk -F ': ' '{print $2}')
GENRE=$(mediainfo "$i" |grep "Genre " | awk -F ': ' '{print $2}')
DATE=$(mediainfo "$i" |grep "Recorded date " | awk -F ': ' '{print $2}')
TRN=$(mediainfo "$i" |grep "Track name/Position" | awk -F ': ' '{print $2}')
COMPOSER=$(mediainfo "$i" |grep "Composer " | awk -F ': ' '{print $2}')

ffmpeg -i "$i" -acodec pcm_s16le -f wav - |\
neroAacEnc -ignorelength -if - -of "${i%.*}".m4a && \

neroAacTag "${i%.*}".m4a -meta:artist="$ARTIST" -meta:title="$TITLE" \
-meta:album="$ALBUM" -meta:genre="$GENRE" -meta:year="$DATE" \
-meta:track="$TRN" -meta:composer="$COMPOSER"

done

It's easy to add other tags such as disc number, comment and so on.

Mediainfo:
http://mediainfo.sourceforge.net/en/Download/Windows
Windows binaries for sed, (g)awk, grep:
http://gnuwin32.sourceforge.net/packages.html

This post has been edited by db1989: May 5 2012, 17:28
Reason for edit: as above
Go to the top of the page
+Quote Post
Takla
post May 5 2012, 07:10
Post #3





Group: Members
Posts: 169
Joined: 14-November 09
Member No.: 74931



I had another look at this because mediainfo is just too slow for this task for anything except occasional use. It is possible to get the metadata from ffmpeg because ffmpeg passes its messages to stderr, which makes it easy to dump into a text file and then grep for whichever fields are wanted. This is massively quicker.

This is what I'm using now:

CODE
#!/bin/bash

function get_metadata ()
{
awk -F ": " '{$1="";$0=substr($0,2)}1'|\
sed 's/[;]/-/g;s/[/]/-/g;s/[<]/-/g;s/[>]/-/g;s/[:]/-/g;s/[|]/-/g'
}

for i in "$@"; do

TAG="${i%.*}"_tag

ffmpeg -i "$i" -acodec pcm_s16le -f wav - 2>"$TAG" |\
neroAacEnc -ignorelength -if - -of "${i%.*}".m4a;

ARTIST=$(grep -m 1 -i ARTIST "$TAG"|get_metadata)
TITLE=$(grep -m 1 -i TITLE "$TAG"|get_metadata)
ALBUM=$(grep -m 1 -i ALBUM "$TAG"|get_metadata)
GENRE=$(grep -m 1 -i GENRE "$TAG"|get_metadata)
TOT=$(grep -m 1 -i TRACKTOTAL "$TAG"|get_metadata)
DATE=$(grep -m 1 -i DATE "$TAG"|get_metadata)
TRN=$(grep -m 1 -i TRACK "$TAG"|get_metadata)
COMPOSER=$(grep -m 1 -i COMPOSER "$TAG"|get_metadata)
COMMENT=$(grep -m 1 -i COMMENT "$TAG"|get_metadata)
DISC=$(grep -m 1 -i DISC "$TAG"|get_metadata)

neroAacTag "${i%.*}".m4a -meta:artist="$ARTIST" -meta:title="$TITLE" \
-meta:album="$ALBUM" -meta:genre="$GENRE" -meta:year="$DATE" \
-meta:track="$TRN" -meta:totaltracks="$TOT" -meta:composer="$COMPOSER" \
-meta:comment="$COMMENT" -meta:disc="$DISC"
rm "$TAG"
done
exit 0

The worrying looking awk expression: it's so awk will print every column after the delimiter ": " because the number of columns and the characters or symbols they might contain is unknown (especially true of long comment fields, some of which can be 100s of words).

The sed command just strips out any characters such as : ; <> | which might otherwise get interpreted as a termination signal (I found neroAacTag will quit on encountering ";" in a comment field).

Anyway this works much better than the mediainfo method, so it is all possible with ffmpeg, neroAac and standard tools after all.

This post has been edited by db1989: May 5 2012, 17:28
Reason for edit: as above
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 User(s) are reading this topic (1 Guests and 0 Anonymous Users)
0 Members:

 



RSS Lo-Fi Version Time is now: 30th August 2014 - 22:10