ffmpeg-python icon indicating copy to clipboard operation
ffmpeg-python copied to clipboard

Trying to Fix the no audio track problem after filters

Open DaedlyKitten opened this issue 4 years ago • 1 comments

After noticing audio tracks are being dropped after applying filters, and as the documentation states:

Some ffmpeg filters drop audio streams, and care must be taken to preserve the audio in the final output. This dilemma is intrinsic to ffmpeg, and ffmpeg-python tries to stay out of the way while users may refer to the official ffmpeg documentation as to why certain filters drop audio. The .audio and .video operators can be used to reference the audio/video portions of a stream so that they can be processed separately and then re-combined later in the pipeline.

Example Process the audio and video portions of a stream independently:

input = ffmpeg.input('in.mp4')
audio = input.audio.filter("aecho", 0.8, 0.9, 1000, 0.3)
video = input.video.hflip()
out = ffmpeg.output(audio, video, 'out.mp4')

So I digged a bit, could be that newer ffmpeg versions had fixed this problem with a more precise way of syntax, For now the audio track WILL BE DROPPED by default with the way this package is compiling the command lines, So for example, if you want to concatenate two parts of the video 1.mp4 (with time stamps of the 2 parts in variable timePairs) :

          streams=[ffmpeg.input('1.mp4',ss=str(t0),to=str(t1),**inputArgs) for (t0,t1) in timePairs] 
          ffmpeg.output(ffmpeg.concat(*streams) ).run()

it will generate the arg: ffmpeg -ss 195.089 -to 212.579 -i 1.mp4 -ss 304.767 -to 420.326 -i 1.mp4 -filter_complex [0][1]concat=n=2[s0] -map [s0] -vcodec libx265 "out.mp4"

Per the ffmpeg document, it simply means you DONT WANT audio tracks in it, otherwise it should be:

ffmpeg -ss 195.089 -to 212.579 -i 1.mp4 -ss 304.767 -to 420.326 -i 1.mp4 -filter_complex [0][0][1][1]concat=n=2:a=1[s0] -map [s0] -vcodec libx265 "out.mp4"

the a=1 means for every segment 1 audio track will be used, which can be omitted, like how by default the omitted v=1 meaning 1 video track every segment is, so [0] video, [0]audio, then [1] video, [1] audio will be the filter result


To fix this temporarily I added an argument 'alsoAudio' into the nodes.py, so it looks like:

class InputNode(Node):
    """InputNode type"""

    def __init__(self, name, args=[], kwargs={},alsoAudio=False):
        super(InputNode, self).__init__(
            stream_spec=None,
            name=name,
            incoming_stream_types={},
            outgoing_stream_type=FilterableStream,
            min_inputs=0,
            max_inputs=0,
            args=args,
            kwargs=kwargs,    
        )
        self.alsoAudio=alsoAudio

in filters.py

kwargs['n'] = int(len(streams) / stream_count) to kwargs['n'] = int(len(streams) / video_stream_count) then in the run.py

def _format_input_stream_name(stream_name_map, edge, is_final_arg=False):
    prefix = stream_name_map[edge.upstream_node, edge.upstream_label]
    if not edge.upstream_selector:
        suffix = ''
    else:
        suffix = ':{}'.format(edge.upstream_selector)
    if is_final_arg: # and isinstance(edge.upstream_node, InputNode):
        fmt = '[{}{}]'.format(prefix, suffix)
    else:
        fmt = '[{}{}]'.format(prefix, suffix)
        fmt+=fmt if edge.upstream_node.alsoAudio else fmt
    return fmt

Add arg alsoAudio=True in your ffmpeg.input to generate audio map in the filter syntax, which is read during the compile in run.py, with the added edge.upstream_node.alsoAudio and it will add itself again for the extra audio track

for example, the above example should be:

 streams=[ffmpeg.input('1.mp4',ss=str(t0),to=str(t1),      alsoAudio=True    ,**inputArgs) for (t0,t1) in timePairs] 
 ffmpeg.output(ffmpeg.concat(*streams,a=1) ).run()

and it will generate the correct output for ffmpeg to run with:

ffmpeg -ss 195.089 -to 212.579 -i 1.mp4 -ss 304.767 -to 420.326 -i 1.mp4 -filter_complex [0][0][1][1]concat=n=2:a=1[s0] -map [s0] -vcodec libx265 "out.mp4"

with audio track in the result file

DaedlyKitten avatar Jun 14 '21 04:06 DaedlyKitten

Is the alsoAudio options still available?

EdoardoPedrotti avatar Jun 02 '22 14:06 EdoardoPedrotti