Avidemux Forum

Avidemux => Main version 2.6 => Topic started by: Dewey on April 05, 2016, 04:13:12 PM

Title: Add second audio track to MKV file
Post by: Dewey on April 05, 2016, 04:13:12 PM
Hi,

I have some mkv files which have an AC3 encoding where I'd like to add a second audio track for playing on my iPad (AC3 not supported). I've managed to achieve this successfully via the GUI (Audio->Select Track->Enable Track 2), where I can then select a pre-saved version of the existing audio file for use in Track 2 as AVIdemux doesn't allow me to create 2 tracks from the single source.

I'd like to automate this with a script as I've quite a few files to get through, but when I try it with a script it throws the attached error :( Any ideas what is going wrong??

I'm running, Ver 2.6.12 64bit on win10

I'm calling it via the following batch cmd;
set avidemux="C:\Program Files\Avidemux\avidemux.exe"
for %%f in (*.mkv) do %avidemux% --load "%%f" --save-raw-audio "E:\iPadConvCache\tmp.wav" --run Test2.js --save "Output\%%f" --quit


I used the GUI to get my base project script up and then trimmed it down to this;
adm = Avidemux()
adm.videoCodec("Copy")
adm.audioClearTracks()
adm.audioAddExternal("E:\iPadConvCache\tmp.wav");
adm.audioAddTrack(0)
adm.audioCodec(0, "copy");
adm.audioAddTrack(1)
adm.audioCodec(1, "Lame", "bitrate=192", "preset=0", "quality=1", "disableBitReservoir=False");
adm.audioSetMixer(1, "STEREO");
adm.setContainer("MKV")


If I only add one audio track in my script it works... which makes me think there's potentially something wrong with my syntax. Its difficult to find information on this, especially whether 'adm.audioAddExternal' is been applied correctly as it doesn't seem to be specifying which track I want to assign it to like the other audio functions have.

Would appreciate anyone's insight here, or other ways of achieving my goal :)

Cheers,
D
Title: Re: Add second audio track to MKV file
Post by: mean on April 05, 2016, 07:09:46 PM
It's all about index
There are N tracks coming from the original video (from 0 to N-1)
Each time you use adm.audioAddExternal(), it gets the next index

So if you have only one track and do
adm.audioClearTracks()
adm.audioAddExternal("/work/samples/2mn.mp3")  # index 1
adm.audioAddExternal("/work/samples/2mn.ac3")  # index 2

and then you map them
adm.audioAddTrack(0) <- track 0 from original file becomes track 0
adm.audioAddTrack(2) <- track 2 (2mn.ac3) becomes track 1
adm.audioAddTrack(1) <- track 1 (2mn.mp3) becomes track 2

There seems to be a bug in the py script generation code when multiple external tracks are present



Title: Re: Add second audio track to MKV file
Post by: Jan Gruuthuse on April 06, 2016, 06:56:46 AM
or make it a 2 step script, each step using its own project.py (no re-encoding, only copy video/audio)
1st step load source video add track 2 -> save new video
2nd step load new saved video from step1, replace track 1 -> save video.
Title: Re: Add second audio track to MKV file
Post by: Dewey on April 07, 2016, 12:25:40 PM
ok, thanks @mean. I think I understand how the indexing works now.

However... I'm still getting the same error :(

Simplifying the code a little based on what @Jan has suggested I have amended my script to just try and tackle the first step; ie add a second audio track;

adm = Avidemux()
adm.videoCodec("Copy")
adm.audioClearTracks()
adm.audioAddExternal("E:\iPadConvCache\tmp.wav");
adm.audioAddTrack(1)
adm.setContainer("MKV")


So based on my understanding this should add the audio to index identifier 1 and then I can map this to track 1 (2nd track). The first, original, track will remain at index 0. [not sure what audioClearTracks does and/or if I need to specify anything with regards to track 0]

Appreciate the help :)

Title: Re: Add second audio track to MKV file
Post by: Jan Gruuthuse on April 07, 2016, 02:17:08 PM
I guess you need to keep information of present track.
- track (0) would be existing/present audiotrack
- track (1) loading wav file, converting to mp3
adm = Avidemux()
adm.videoCodec("Copy")
adm.audioClearTracks()
adm.setSourceTrackLanguage(0,"eng")
adm.audioAddExternal("E:\iPadConvCache\tmp.wav")
adm.setSourceTrackLanguage(1,"deu")
adm.audioAddTrack(0)
adm.audioCodec(0, "copy");
adm.audioSetDrc(0, 0)
adm.audioSetShift(0, 0,0)
adm.audioAddTrack(1)
adm.audioCodec(1, "Lame", "bitrate=128", "preset=0", "quality=1", "disableBitReservoir=False");
adm.audioSetDrc(1, 0)
adm.audioSetShift(1, 0,0)
adm.setContainer("MKV", "forceDisplayWidth=False", "displayWidth=1280")
Title: Re: Add second audio track to MKV file
Post by: Jan Gruuthuse on April 07, 2016, 02:30:56 PM
Or you could
- load wav as 1st track and convert to mp3 [= track(0)]
- take existing audio track in video to 2nd track [= track(1)]

adm = Avidemux()
adm.videoCodec("Copy")
adm.audioClearTracks()
adm.setSourceTrackLanguage(0,"eng")
adm.audioAddExternal("E:\iPadConvCache\tmp.wav")
adm.setSourceTrackLanguage(1,"eng")
adm.audioAddTrack(1)
adm.audioCodec(0, "Lame", "bitrate=192", "preset=0", "quality=1", "disableBitReservoir=False");
adm.audioSetDrc(0, 0)
adm.audioSetShift(0, 0,0)
adm.audioAddTrack(0)
adm.audioCodec(1, "copy");
adm.audioSetDrc(1, 0)
adm.audioSetShift(1, 0,0)
adm.setContainer("MKV", "forceDisplayWidth=False", "displayWidth=1280")


I guess, adm.audioClearTracks() is clearing previous/remaining from previous operations
Title: Re: Add second audio track to MKV file
Post by: mean on April 09, 2016, 07:39:52 AM
 you have source index : 0--N from the source video, n+1,,... from external audio tracks
and the target index, in the output file

Clear empties the target index

So if you do

adm = Avidemux()
adm.audioAddExternal("E:\iPadConvCache\tmp.wav");

  you have source index [0]  =  from video
  you have source index [1]  = from  tmp.wav

adm.audioClearTracks()
Target index empty


adm.audioAddTrack(1)

Add source index 1, that becomes target index 0 => only one track, tmp.wav
Title: Re: Add second audio track to MKV file
Post by: Dewey on April 09, 2016, 07:58:00 AM
Hi Jan, unfortunately neither works - I get the same error :(

Taking a step back, and remembering that I'm using win64, what is the convention for a script file as I see on-line this varies;

Very confusing...  :o

If I can get this coding convention right first it'll probably help remove spurious issues.

Cheers,
D
Title: Re: Add second audio track to MKV file
Post by: Dewey on April 09, 2016, 08:06:20 AM
Thanks @mean. I think I understand how it works. I've just tried what you suggested but end up with the same error... I'm starting to think there is a basic setup issue that is clouding my ability to test what you guys are suggesting - See post above ^^
Title: Re: Add second audio track to MKV file
Post by: Jan Gruuthuse on April 09, 2016, 09:08:36 AM
do what you have to do in Avidemux GUI, load video, change audio tracks, ...

Once done, in Avidemux Menu: File
you should find some Project items
Save as in each found project item.
Close video and load the Saved Project in corresponding found project item.
It would give you an indication on what works and what isn't working.

Problematic issues could be (none standard Eglish OS):
- names (file & path) with spaces or non standard us ascii character in it.
- don't apply/call adm.audioClearTracks() second time in script on loaded video (would erase previously made settings)
- user owner access rights to certain locations
...

This would also give you an idea of used syntax in the working script (Project)
Title: Re: Add second audio track to MKV file
Post by: Dewey on April 09, 2016, 12:16:04 PM
nothing is non-standard, so I don't think its that...

however, upon recreating the script via the GUI as you suggested I was trying different combinations and decided to leave the video loading code line, adm.loadVideo("blah blah.mkv"), in the script and Bingo! Everything worked perfectly :)

So... I'm guessing this line of code needs to be in there to define the file. The question is, how do I parse it in as a variable given I'm launching from a batch file that cycles through the entire directory of files.

This is my batch file code;
set avidemux="C:\Program Files\Avidemux\avidemux.exe"
for %%f in (*.mkv) do %avidemux% --load "%%f" --save-raw-audio "E:\iPadConvCache\tmp.wav" --run Test2.js --save "Output\%%f" --quit


Not sure why I'm seeing this behavior but happy that we've almost found the solution  :)

Thanks,
D
Title: Re: Add second audio track to MKV file
Post by: mean on April 09, 2016, 12:36:01 PM
you can do that directly with avidemux
See an example here
https://github.com/mean00/avidemux2/blob/master/autononreg/py/sample_script/convert_avi_to_x264_mkv.py
Title: Re: Add second audio track to MKV file
Post by: Dewey on April 10, 2016, 12:31:56 AM
Any idea on the syntax to save the audio file? If I loop through the files in the script I'll need to extract the audio in there too (currently the batch file is extracting cmd is doing it).

If it's not possible I guess I can set it up in 2 passes, first extract audios via the batch cmd then run the script.
Title: Re: Add second audio track to MKV file
Post by: mean on April 10, 2016, 05:24:57 AM
adm.saveAudio(tracknumber, outputfile)

i.e.

adm.saveAudio(0,"foo.mp3")
Title: Re: Add second audio track to MKV file
Post by: Dewey on April 10, 2016, 04:56:28 PM
thanks @mean. I tried this (adm.saveAudio) but for some reason it wouldn't let me save and use in the script, would just drop out - I guess for the same reason it won't let me do it in the GUI... forcing me to do it in 2 steps, which is ok.

Back to the main issue, I've taken a look at the code you posted on github, modified it for my needs but its given the same error message I posted originally. Interestingly, if I add adm.loadVideo("blah blah.mkv") to the #MAIN code section where everything is specified, again it ignores what I'm passing to it (in the for loop) and it works! This time however, thanks to the fact that your code does some printing to the log file I think I've found the problem, the specification of the file location is having issues with the forward/back slashes - I remember reading somewhere issues with this across platforms.

[Script] Tinypy INFO - E:/iPadConvCache/\Test.mkv=>E:/iPadConvCache/\Test.mkv.mkv

Any ideas on how I can correct this? I've tried using the replace function but it throws an error, not sure if .replace is part of an additional library that I need to load first.
     filein = filein.replace("/\","/");

I've checked the log (for a successful run and erroneous) and because the file string is wrong (in this current case and most likely in the original batch loading version I was playing with) it hasn't successfully loaded the video and thus when you load the external audio it gets an Index of 0 (rather than 1, in success state) and then throws a 'Pool index is out of bound error' because its got no file (video/audio streams) to apply it to - this is my theory anyway ;)

New Code;
#PY  <- Needed to identify #
#--automatically built--

ext="mkv";
#
def convert(filein):
    filein = filein.replace("/\","/");
fileout=filein+".mkv"
    print(filein+"=>"+fileout)
    if(0 == adm.loadVideo(filein)):
        ui.displayError("oops","cannot load "+filein)
        raise
       
    adm.save(fileout)
    print("Done")

# Main
adm = Avidemux()
adm.videoCodec("Copy")
adm.audioClearTracks()
adm.audioAddExternal("E:/iPadConvCache/tmp.wav")
adm.audioAddTrack(0)
adm.audioCodec(0, "copy");
adm.audioSetDrc(0, 0)
adm.audioSetShift(0, 0,0)
adm.audioAddTrack(1)
adm.audioCodec(1, "Lame", "bitrate=192", "preset=0", "quality=1", "disableBitReservoir=False");
adm.audioSetMixer(1, "STEREO");
adm.audioSetDrc(1, 0)
adm.audioSetShift(1, 0,0)
adm.setContainer("MKV", "forceDisplayWidth=False", "displayWidth=1280")

#
folder="E:/iPadConvCache/"
list=get_folder_content(folder,ext)
for i in list:
convert(i)
print("Done")
Title: Re: Add second audio track to MKV file
Post by: mean on April 10, 2016, 05:06:55 PM
Each time you load a file, you reset a lot of settings
You should not have to do replace / by  \
If needed it should be \/ to //
Title: Re: Add second audio track to MKV file
Post by: Dewey on April 11, 2016, 01:07:59 PM
What's the syntax required for this line? I've tried as you suggested and I can't get it to work.

filein=filein.replace("\/", "/");


[Script] Tinypy INFO - E:/iPadConvCache/\Test.mkv=>E:/iPadConvCache/\Test.mkv.mkv

Since I think I'm trying to change the /\ string piece to just a forward / in the above logfile output, I also tried a few other options, but again I'm not really sure what I'm doing  :-\

filein=filein.replace(/\\/, "/");

googling it, it seems like my issue is related to the fact the / is seen as an escape character and I need to remove it, unfortunately I'm not a coder so I'm struggling with the syntax. Am I on the right track here?
Title: Re: Add second audio track to MKV file
Post by: Jan Gruuthuse on April 11, 2016, 01:47:21 PM
Windows \ (back slash): E:\iPadConvCache\Test.mkv.mkv
Linux / (forward slash): ~/Downloads/Test.mkv

Do note you have twice the file extension: .mkv.mkv
Title: Re: Add second audio track to MKV file
Post by: Dewey on April 11, 2016, 03:17:48 PM
Hi Jan, Under win10 x64 / (forward slash) seems to be the convention, which I thought was odd (I grew up with MSDOS) initially... Tested with backlashes early on and it failed.

The double mkv is just a place holder for the moment as I don't want to over write the original - eventually I want to move it into a sub directory but struggling at the moment to just get the file string in the right format :(

Any help with the syntax for the .replace would be great!

Cheers,
D
Title: Re: Add second audio track to MKV file
Post by: Jan Gruuthuse on April 12, 2016, 06:55:31 AM
Sorry m8, don't have windows to test on these.
Title: Re: Add second audio track to MKV file
Post by: Dewey on April 12, 2016, 11:51:33 AM
no worries, appreciate the input so far.

@mean, any help with the syntax? I'm a little stuck :(
Title: Re: Add second audio track to MKV file
Post by: AQUAR on April 12, 2016, 12:47:47 PM
The windows command line interpreter uses only \ slashes as path separators.
But windows itself accepts either (/ or \ as path separators (try it in windows explorer!).

For info wrt the post below: 
AddMP3Audio.bat = CLI script = only \
AddMP3Audio.py = tiny python script = windows API = \ or /
Title: Re: Add second audio track to MKV file
Post by: Dewey on April 12, 2016, 01:17:04 PM
oh dear... it's always the small bugs that seem to keep you hunting for days on end  :o

So, I finally got this working - yay!! - thanks @mean & @Jan Gruuthuse, your help was appreciated.

My issue in the end was with the slash convention (w10 x64 requires forward slashes for the file string '/') in the file string, as I'd started to suspect. However, rather than apply this change to my earlier tests (the soln was actually in post #3) I was plowing ahead with ever more complex options to try and resolve this.

For the Dev Team: What would be good here is if the error thrown could give more useful information. Like file not found, or something. Although I suspect because the backslash in the file string is an escape character you might not be able to catch this before it throws the error...

For any user stumbling across this thread:
First check the file string convention of your os, then you can implement as follows. Was all very minor code in the end;

Batch File: AddMP3Audio.bat
set avidemux="C:\Program Files\Avidemux\avidemux.exe"
for %%f in (*.mkv) do %avidemux% --load "%%f" --save-raw-audio "E:\iPadConvCache\audiodump" --run "AddMP3Audio.js" --save "Output\%%f" --quit


AVIdemux Script: AddMP3Audio.js
#PY  <- Needed to identify #
#--automatically built--

adm = Avidemux();
adm.audioAddExternal("E:/iPadConvCache/audiodump");
adm.audioAddTrack(1);
adm.audioCodec(1, "Lame", "bitrate=192", "preset=0", "quality=1", "disableBitReservoir=False");
adm.audioSetMixer(1, "STEREO");
adm.setContainer("MKV", "forceDisplayWidth=False", "displayWidth=1280");


Simples  :P
Title: Re: Add second audio track to MKV file
Post by: Jan Gruuthuse on April 13, 2016, 04:51:02 AM
Nicely done, just one remark "AddMP3Audio.js" should be "AddMP3Audio.py". See 1st line of your script
Quote#PY  <- Needed to identify #
indicating Tinypy scripting is used. ;)
Title: [Solved!] Re: Add second audio track to MKV file
Post by: Dewey on April 14, 2016, 12:38:02 PM
Noted... and Changed. Script still works. Thanks again for your help.
D