Log in

View Full Version : Specify input duration of one of ffmpeg's amerge/join inputs


Reino
20th October 2013, 16:06
Hello,

I've been trying to create a 4ch (quad) TAK image from "Myths and Legends" by David Arkenstone (http://www.discogs.com/David-Arkenstone-Myths-Legends/release/3730963). Now the things is, cd2 has 228732 more samples than cd1. There are of course several ways to accomplish this:

- Audacity
Audacity works with temporary files though and it doesn't appear to send channelmask information through pipe.

- Avisynth
a1=BassAudioSource("Audiotrack_1.01.flac")
...
a9=BassAudioSource("Audiotrack_1.09.flac")
b1=BassAudioSource("Audiotrack_2.01.flac")
...
b9=BassAudioSource("Audiotrack_2.09.flac")

front=a1+a2+a3+a4+a5+a6+a7+a8+a9+a9.AudioTrim(0,228732/44100.0).Amplify(0)
back=b1+b2+b3+b4+b5+b6+b7+b8+b9
MergeChannels(front,back)

ConvertAudioTo16bit()Since MergeChannels, just like MixAudio, adopts the first input's duration, you'd have to make both inputs equally long. By using avs2pipemod.exe -extwav (to copy channelmask info) this works fine in the end.

- FFMpeg
Now with ffmpeg, the same issue.
ffmpeg.exe -i "Audiotrack_1.01.flac" ... -i "Audiotrack_2.09.flac" -filter_complex "[0:0][1:0][2:0][3:0][4:0][5:0][6:0][7:0][8:0]
concat=n=9:v=0:a=1[front];[9:0][10:0][11:0][12:0][13:0][14:0][15:0][16:0][17:0]concat=n=9:v=0:a=1;[front][back]join=
channel_layout=quad[mix]" -map [mix] -f wav - | Takc.exe -e -pMax -ihs - "Album.tak"

If inputs do not have the same duration, the output will stop with the shortest.This applies to join as well, because Album.tak is constantly 228732 samples short.
Funny thing is, unlike amerge/join, amix actually has a duration command:
[B]‘duration’
How to determine the end-of-stream.
‘longest’
Duration of longest input. (default)
‘shortest’
Duration of shortest input.
‘first’
Duration of first input.
So, unless anyone knows a command to make [front] just as long as [back], I think I'd have to do a feature-request for amerge/join.

raffriff42
21st October 2013, 00:32
>cd2 has 228732 more samples than cd1
Where does the difference appear? Better find out. For example, if cd2 has an extra bit of audio at the start, it would throw you out of sync by 5 seconds throughout. Hopefully cd2 just has more silence at the end, as this is much easier to fix: I would point you to apad (http://www.ffmpeg.org/ffmpeg-all.html#apad) to add silence to cd1, and use the -shortest switch as mentioned in the link -- now cd2 will be the new shortest source. If you need to add silence at the beginning, try adelay (http://www.ffmpeg.org/ffmpeg-all.html#adelay). If in the middle, I dunno. Good luck!

Reino
21st October 2013, 22:41
As you can see in the Avisynth script, the difference appears at the end (and it's not more silence, but a whole different track). ;) All tracks on cd2 have the same amount of samples as their counterparts on cd1, except track 9 which is 228732 samples longer. Alignment is not an issue. Track 9 is just a bit longer.

I thought, why not mimic Avisynth's AudioTrim().Amplify()-method? So yesterday I already tried...
ffmpeg.exe -i "Audiotrack_1.01.flac" ... -i "Audiotrack_2.09.flac" -filter_complex "[8:0]atrim=end_sample=228732,volume=0[pad];
[0:0][1:0][2:0][3:0][4:0][5:0][6:0][7:0][8:0][pad]concat=n=10:v=0:a=1[front];[9:0][10:0][11:0][12:0][13:0][14:0][15:0][16:0][17:0]
concat=n=9:v=0:a=1;[front][back]join=channel_layout=quad[mix]" -map [mix] -f wav - | Takc.exe -e -pMax -ihs -
"Album(ffmpeg,atrim,volume).tak"
...but the strange thing is, isolating -map [front] puts out the correct length (49:01.813 (129733968 samples), the same length as -map [back] / cd2), but -map [mix] puts out again the length of cd1 (48:56.627 (129505236 samples))...wtf?! :confused:

Today I gave your suggestion a try and in the end came up with this:
ffmpeg.exe -i "Audiotrack_1.01.flac" ... -i "Audiotrack_2.09.flac" -filter_complex "[0:0][1:0][2:0][3:0][4:0][5:0][6:0][7:0][8:0]
concat=n=9:v=0:a=1[B],apad=pad_len=228732[front];[9:0][10:0][11:0][12:0][13:0][14:0][15:0][16:0][17:0]concat=n=9:v=0:a=1[back];
[front][back]join=channel_layout=quad[mix]" -map [mix] -f wav - | Takc.exe -e -pMax -ihs - "Album(ffmpeg,apad).tak"It has the correct length and the audio, compared to the Avisynth version, is bit-exact according to Binary Comparator (http://www.foobar2000.org/components/view/foo_bitcompare) (a foobar2000 plugin):All tracks decoded fine, no differences found.

Comparing:
"D:\Album(ffmpeg,apad).tak" / index: 9
"D:\Album(avisynth).tak" / index: 9
No differences in decoded data found.A lot simpler than atrim and volume of course! Thanks for your help, raffriff42.

raffriff42
22nd October 2013, 02:03
Nice work, CoRoNe!
>Thanks for your help, raffriff42.
I understood that one sentence, but the rest of your post is a blur! I need to break it down to understand what you did. Here's your first method: ffmpeg.exe

-i "Audiotrack_1.01.flac" ... -i "Audiotrack_2.09.flac"
// load a set of Flac audio sources

-filter_complex
// audio filter

"[8:0]atrim=end_sample=228732,volume=0[pad];
// make a silent audio pad:
// "[8.0]" (use file 8, stream 0)
// "trim" (main filter for this action)
// "end_sample=228732" (length of pad)
// "volume=0" (silence)
// "[pad]" (name for this new stream)

[0:0][1:0][2:0][3:0][4:0][5:0][6:0][7:0][8:0][pad]concat=n=10:v=0:a=1[front];
// concatenate sources [0.0] thru [8.0] (that is, files 0 through 8) and [pad]:
// "concat" (main filter for this action)
// "n=10" (10 sources)
// "v=0" (video stream count = 0)
// "a=1" (audio stream count = 1)
// "[front]" (name for this concatenated stream)

[9:0][10:0][11:0][12:0][13:0][14:0][15:0][16:0][17:0]concat=n=9:v=0:a=1[back];
// concatenate sources [9.0] thru [17.0]:
// "concat" (main filter for this action)
// "n=9" (9 sources)
// "v=0" (video stream count = 0)
// "a=1" (audio stream count = 1);
// "[back]" (name)

// (not stated: all streams are 2 audio channels each)

[front][back]join=channel_layout=quad[mix]"
// mix [front] & [back] for final quadrophonic soundtrack
// "join" (main filter for this action)
// "channel_layout=quad" (specify the channel layout)
// "[mix]" (name)

// end of filter string

-map [mix] -f wav -
// take the [mix] signal, write to stdout in WAV format...

| Takc.exe -e -pMax -ihs - "Album(ffmpeg,atrim,volume).tak"
// ...and pass to Takc.exe, which creates the final .TAK file

OK here's the second method (just the changed part): "[0:0][1:0][2:0][3:0][4:0][5:0][6:0][7:0][8:0]concat=n=9:v=0:a=1,apad=pad_len=228732[front];
// concatenate sources [0.0] thru [8.0] as before (no pad stream required) ...
// ",apad=pad_len=228732" (pad audio 228732 samples

[9:0][10:0][11:0][12:0][13:0][14:0][15:0][16:0][17:0]concat=n=9:v=0:a=1[back];
// concatenate sources [9.0] thru [17.0] as before ...

[front][back]join=channel_layout=quad[mix]"
// mix [front] & [back] as before ... ...I learned something today, thanks! Maybe this will help others learning ffmpeg filter commands.

Reino
22nd October 2013, 21:22
You're Fraps' author, right? The last person I expect to be learning something from me. But you're welcome nontheless of course. ;)
You've analysed it right; per filterchain. A semicolon ends a filterchain and with a comma you can combine filters together in time.

Btw, I usually consult http://ffmpeg.org/ffmpeg-all.html (http://ffmpeg.org/ffmpeg-all.html), but I don't know if you've noticed, but it doesn't seem complete. The following is 34.10 apad (http://ffmpeg.org/ffmpeg-all.html#apad):
Pad the end of a audio stream with silence, this can be used together with -shortest to extend audio streams to the same length as the video stream.
While ffmpeg.exe -h filter=apad shows you:
Filter apad
Pad audio with silence.
Inputs:
#0: default (audio)
Outputs:
#0: default (audio)
apad AVOptions:
packet_size <int> ..F.A. set silence packet size (from 0 to INT_MAX) (default 4096)
pad_len <int64> ..F.A. number of samples of silence to add (from 0 to I64_MAX) (default 0)
whole_len <int64> ..F.A. target number of samples in the audio stream (from 0 to I64_MAX) (default 0)

This filter has support for timeline through the 'enable' option.
Maybe this will help others learning ffmpeg filter commands.I hope so. Maybe tebasuna's idea wasn't such a bad idea. Perhaps I'll put together something one day.
Maybe is a good idea open a post like "ffmpeg audio mannagement" to explain alternatives to common audio tasks than be solved with eac3to, sox or BeHappy/AviSynth.

25½ seconds sample (http://www.mediafire.com/download/6hi1c1e899aslfu/Across_the_River_sample.opus), for those interested

raffriff42
22nd October 2013, 22:16
>You're Fraps' author, right?
No, haha, just active on the Fraps support board, and authored a few auxiliary tools (https://sourceforge.net/users/raffriff42).

> I don't know if you've noticed, but it doesn't seem complete
I first realized this when I saw you used "pad_len", which as you mention, is not to be found on that page. Doh!

>Maybe tebasuna's idea wasn't such a bad idea.
Agreed. There's a definite lack of working examples on line.