News:

--

Main Menu

Batch Save Audio Only

Started by TheTooleMan, January 09, 2023, 04:06:11 PM

Previous topic - Next topic

TheTooleMan

I posted back in July 2022 about the SaveAudio method and finally had a chance to try to make it work. I did not succeed.

I need to convert and export audio from a video with an AC3 soundtrack. The output file should be PCM and stored as WAV audio. Trying to run the SaveAudio statement in a script produces a Key Error exception referring to SaveAudio but without any additional info.

Last time I tried to post code, it was killed by an algorithm. Let me know if I can PM a code sample to you. Thanks.

eumagga0x2a

Quote from: TheTooleMan on January 09, 2023, 04:06:11 PMI need to convert and export audio from a video with an AC3 soundtrack. The output file should be PCM and stored as WAV audio. Trying to run the SaveAudio statement in a script produces a Key Error exception referring to SaveAudio but without any additional info.

I don't know how interactive your script should be, here follows a working example for an already loaded video with at least 3 audio tracks and the selection already manually set:

adm = Avidemux()
gui = Gui()
adm.audioClearTracks()
trackNo = 2
trackStr = str(trackNo + 1)
if adm.audioTotalTracksCount() <= trackNo:
    gui.displayError("Error", "Cannot add audio track No. " + trackStr + ", total tracks: " + str(adm.audioTotalTracksCount()))
    return 0
adm.audioAddTrack(trackNo)
adm.audioCodec(0, "PCM", "output_mode=0")
outname = "/tmp/test/audio-track-converted-to-pcm.wav"
if not adm.saveAudio(trackNo, outname):
    gui.displayError("Error", "Error saving audio track No. " + trackStr + " to \"" + outname + "\"")
    return 0
gui.displayInfo("Success", "Track No. " + trackStr + " exported as \"" + outname + "\"")
return 1

Quote from: TheTooleMan on January 09, 2023, 04:06:11 PMLast time I tried to post code, it was killed by an algorithm. Let me know if I can PM a code sample to you.

Please don't hesitate to use PM when CleanTalk prevents you from posting. I cannot overrule CleanTalk, but can either reply directly or post the content as a quote.

TheTooleMan

Thanks for the example. I got the command to work... sort of. Using a file name as a variable seemed to make a difference. I ran a procedure that exported a WAV of one segment of a file successfully, but I need to export a WAV from each of several segments in a called procedure. So far I haven't had success with a call to a procedure that traverses the collection of segments, but will persevere.

Are the method/function names used in tinypy case sensitive? That might have made a difference.

My videos only have one audio track, so I should be good with using 0 as the track number.

Thanks again.

eumagga0x2a

Quote from: TheTooleMan on January 10, 2023, 04:45:32 PMI ran a procedure that exported a WAV of one segment of a file successfully, but I need to export a WAV from each of several segments in a called procedure.

You might try to adapt bits from the (untested) script below:

adm = Avidemux()
ed = Editor()
gui = Gui()

Counter = 0
mark1 = 0
mark2 = 0

nbSeg = ed.nbSegments()

if not nbSeg:
    gui.displayError("Error", "No video loaded, nothing to do, bye")
    return 0

if not adm.audioTotalTracksCount():
    gui.displayError("Error", "No audio track, nothing to do, bye")
    return 0

if nbSeg > 100:
    gui.displayInfo("Warning", "Maximum of 100 segments supported, but got " + str(nbSeg))
    nbSeg = 100

filename = ed.getRefVideoName(0)
if filename is None:
    gui.displayError("Error", "Cannot obtain reference video filename")
    return 0

filename = (splitext(filename))[0]
filename = basename(filename)

if filename is None:
    gui.displayError("Error", "Cannot obtain input basename")
    return 0

filename = "audio-from-" + filename;

# Replace gui.dirSelect() below with output directory path for unattended operation.
outdir = gui.dirSelect("Select output folder")
if outdir is None:
    gui.displayInfo("Warning", "No output folder selected, cannot proceed")
    return

leadingZero = ""

adm.audioClearTracks()
adm.audioAddTrack(0)
adm.audioCodec(0, "PCM", "output_mode=0")

for segmentIdx in range(nbSeg):
    mark2 += ed.getDurationForSegment(segmentIdx)
    if segmentIdx < 10:
        leadingZero = "0"
    adm.markerA = mark1
    adm.markerB = mark2
    Counter += adm.saveAudio(0, outdir + "/" + filename + "-segment-" + leadingZero + str(segmentIdx) + "." + ext)
    mark1 = mark2

gui.displayInfo("Finished", str(Counter) + " audio segments out of " + str(nbSeg) + " converted")
return 1

Quote from: TheTooleMan on January 10, 2023, 04:45:32 PMAre the method/function names used in tinypy case sensitive?

Yes, they are.

eumagga0x2a

Quote from: eumagga0x2a on January 10, 2023, 10:29:05 PM    Counter += adm.saveAudio(0, outdir + "/" + filename + "-segment-" + leadingZero + str(segmentIdx) + "." + ext)

Oops, please replace this with

    Counter += adm.saveAudio(0, outdir + "/" + filename + "-segment-" + leadingZero + str(segmentIdx) + ".wav")

TheTooleMan

Quote from: eumagga0x2a on January 10, 2023, 10:29:05 PM
Quote from: TheTooleMan on January 10, 2023, 04:45:32 PMAre the method/function names used in tinypy case sensitive?

Yes, they are.
Aha! That probably explains my success. I will test your code sample soon. Thank you again.

eumagga0x2a

You might also want to modify

# Replace gui.dirSelect() below with output directory path for unattended operation.
outdir = gui.dirSelect("Select output folder")
if outdir is None:
    gui.displayInfo("Warning", "No output folder selected, cannot proceed")
    return

to return a value (e.g. 0) at least for the sake of uniformity. tinyPy probably won't complain about missing return value, but the mere fact that it is missing hurts the eye and the mind :-)

TheTooleMan

Thanks again! This morning, I succeeded in exporting the video and audio from each segment to MP4 and WAV files, respectively.

I found it better to copy the video and audio in one loop through the segments, then set the audio codec to PCM, loop through the segments again to convert and save it.

The existing error checking for the video process was sufficiently robust to serve for the audio export process, so I did not duplicate all of it. I know these videos only have one audio track, and I realize I would need to modify the code to make it handle multiple audio tracks. Quick and dirty is fine for my needs!  8)