Пример #1
0
    def test_fix_preroll_buffering_with_trim(self):
        """
        We can fix buffering occurred from preroll by using trim filter.
        """
        ff = self.ffmpeg
        ff < self.preroll
        ff < self.source

        output = outputs.output_file('original.mp4',
                                     codecs.VideoCodec("libx264"))
        original = outputs.output_file('original.mp4',
                                       codecs.VideoCodec("libx264"))

        preroll_stream = self.preroll.streams[0]
        source_stream = self.source.streams[0]

        concat = preroll_stream | filters.Concat(VIDEO)
        source_stream | concat

        split = concat | filters.Split(VIDEO)

        split > output

        pd = preroll_stream.meta.duration
        sd = source_stream.meta.duration
        trim = split | filters.Trim(VIDEO, start=pd, end=pd + sd)

        trim | filters.SetPTS(VIDEO) > original

        ff > original
        ff > output

        ff.check_buffering()
Пример #2
0
    def test_handle_codec_copy_with_other_filters(self):
        """ vcodec=copy with separate transcoded output."""
        ff = self.ffmpeg
        ff < self.source

        cv0 = codecs.VideoCodec('copy')
        ca0 = codecs.AudioCodec('copy')
        ff > outputs.output_file('/tmp/copy.flv', cv0, ca0)

        cv1 = codecs.VideoCodec('libx264')
        ca1 = codecs.AudioCodec('aac')
        self.source | filters.Scale(640, 360) > cv1
        self.source > ca1

        ff > outputs.output_file('/tmp/out.flv', cv1, ca1)

        self.assert_ffmpeg_args(
            '-i', 'source.mp4',
            '-filter_complex',
            '[0:v]scale=w=640:h=360[vout0]',
            '-map', '0:v',
            '-c:v', 'copy',
            '-map', '0:a',
            '-c:a', 'copy',
            '/tmp/copy.flv',
            '-map', '[vout0]',
            '-c:v', 'libx264',
            '-map', '0:a',
            '-c:a', 'aac',
            '/tmp/out.flv')
Пример #3
0
    def test_shortcut_outputs_with_codec(self):
        """ Check ff > output shortcut if codecs list specified."""
        ff = FFMPEG(input=inputs.input_file("input.mp4"))
        scaled = ff.video | filters.Scale(width=1280, height=720)

        with self.assertRaises(RuntimeError):
            codec = codecs.VideoCodec("libx264")
            out = ff > outputs.output_file("output.mp4", codec)
            # at this moment codec is connected to ffmpeg input stream directly
            # so scaled video stream could not be connected to output
            scaled > out

        codec = codecs.VideoCodec("libx264")
        out = scaled > outputs.output_file("output.mp4", codec)
        ff > out
Пример #4
0
    def setUp(self) -> None:
        super().setUp()
        self.video_metadata = video_meta_data(width=1920,
                                              height=1080,
                                              dar=1.777777778,
                                              par=1.0,
                                              duration=300.0,
                                              frame_rate=10.0,
                                              frame_count=3000)
        self.source_audio_duration = 200.0
        self.source_sampling_rate = 48000
        self.source_samples_count = (self.source_audio_duration *
                                     self.source_sampling_rate)
        self.source_audio_bitrate = 128000
        self.audio_metadata = audio_meta_data(
            duration=self.source_audio_duration,
            sampling_rate=self.source_sampling_rate,
            samples_count=self.source_samples_count,
            bit_rate=self.source_audio_bitrate,
        )
        self.target_audio_bitrate = 64000

        self.source = inputs.Input(
            input_file='input.mp4',
            streams=(inputs.Stream(VIDEO, meta=self.video_metadata),
                     inputs.Stream(AUDIO, meta=self.audio_metadata)))
        self.output = outputs.output_file(
            'output.mp4', codecs.VideoCodec('libx264'),
            FdkAAC(bitrate=self.target_audio_bitrate))
        self.input_list = inputs.InputList((self.source, ))
        self.output_list = outputs.OutputList((self.output, ))
        self.fc = FilterComplex(self.input_list, self.output_list)
Пример #5
0
    def test_reuse_input_files(self):
        """ Reuse input files multiple times."""
        ff = self.ffmpeg
        ff < self.source
        v = self.source.streams[0]
        a = self.source.streams[1]

        ff > self.output

        cv1 = codecs.VideoCodec('copy')
        ca1 = codecs.AudioCodec('copy')
        out1 = outputs.output_file('/tmp/out1.flv', cv1, ca1)
        v > cv1
        a > ca1
        ff > out1
        self.assert_ffmpeg_args(
            '-i', 'source.mp4',
            '-map', '0:v',
            '-c:v', 'libx264', '-b:v', '3600000',
            '-map', '0:a',
            '-c:a', 'aac', '-b:a', '192000',
            'output.mp4',
            '-map', '0:v',
            '-c:v', 'copy',
            '-map', '0:a',
            '-c:a', 'copy',
            '/tmp/out1.flv',
        )
Пример #6
0
    def test_no_audio_if_no_codecs_found(self):
        """ If no audio codecs specified, set -an flag for an output."""
        ff = self.ffmpeg
        ff < self.source

        output = outputs.output_file('out.mp4', codecs.VideoCodec('libx264'))
        ff.video | filters.Scale(640, 360) > output
        ff > output

        self.assert_ffmpeg_args('-i', 'source.mp4', '-filter_complex',
                                '[0:v]scale=w=640:h=360[vout0]', '-map',
                                '[vout0]', '-c:v', 'libx264', '-an', 'out.mp4')
Пример #7
0
    def test_tee_muxer(self):
        """ tee muxer args."""
        ff = FFMPEG('/tmp/input.mp4')

        cv0 = codecs.VideoCodec('libx264')
        ca0 = codecs.AudioCodec('aac')
        out0 = HLSMuxer('http://ya.ru/1.m3u8', segment_size=2)

        out1 = HLSMuxer('http://ya.ru/2.m3u8', manifest_size=5)
        ff.add_output(TeeMuxer(out0, out1), cv0, ca0)

        expected = [
            'ffmpeg', '-i', '/tmp/input.mp4', '-map', '0:v', '-c:v', 'libx264',
            '-map', '0:a', '-c:a', 'aac', '-f', 'tee',
            '[f=hls:hls_time=2]http://ya.ru/1.m3u8|'
            '[f=hls:hls_list_size=5]http://ya.ru/2.m3u8'
        ]
        self.assertEqual(ff.get_args(), ensure_binary(expected))
Пример #8
0
    def test_handle_codec_copy(self):
        """ vcodec=copy connects source directly to muxer."""
        ff = self.ffmpeg
        ff < self.source

        cv0 = codecs.VideoCodec('copy')
        ca0 = codecs.AudioCodec('aac', bitrate=128000)

        ff.audio | Volume(20) > ca0

        ff > outputs.output_file('/tmp/out.flv', cv0, ca0)
        self.assert_ffmpeg_args(
            '-i', 'source.mp4',
            '-filter_complex',
            '[0:a]volume=20.00[aout0]',
            '-map', '0:v',
            '-c:v', 'copy',
            '-map', '[aout0]',
            '-c:a', 'aac', '-b:a', '128000',
            '/tmp/out.flv'
        )
Пример #9
0
    def setUp(self) -> None:
        super().setUp()
        self.video_metadata = video_meta_data(width=1920,
                                              height=1080,
                                              dar=1.777777778,
                                              par=1.0,
                                              duration=300.0,
                                              frame_rate=10.0,
                                              frame_count=3000)
        self.audio_metadata = audio_meta_data(duration=200.0,
                                              sampling_rate=48000,
                                              samples_count=200 * 48000)

        self.source = inputs.Input(
            input_file='input.mp4',
            streams=(inputs.Stream(VIDEO, meta=self.video_metadata),
                     inputs.Stream(AUDIO, meta=self.audio_metadata)))
        self.output = outputs.output_file('output.mp4',
                                          codecs.VideoCodec('libx264'),
                                          codecs.AudioCodec('libfdk_aac'))
        self.input_list = inputs.InputList((self.source, ))
        self.output_list = outputs.OutputList((self.output, ))
        self.fc = FilterComplex(self.input_list, self.output_list)
Пример #10
0
    def test_detect_trim_buffering(self):
        """
        When trim and concat filters are used for editing timeline, buffering
        may occur if order of scenes in output file does not match order of same
        scenes in input file.
        """
        cases = [
            (False, [1.0, 2.0], [2.0, 3.0]),
            (True, [2.0, 3.0], [1.0, 2.0]),
            (True, [2.0, 3.0], [2.0, 4.0]),
        ]
        for case in cases:
            with self.subTest(case):
                raises, first, second = case
                ff = FFMPEG()
                s1 = inputs.Stream(VIDEO, self.source.streams[0].meta)
                s2 = inputs.Stream(VIDEO, self.source.streams[1].meta)

                ff < inputs.input_file('input.mp4', s1, s2)
                split = ff.video | filters.Split(VIDEO)
                t1 = split | filters.Trim(VIDEO, *first)
                p1 = t1 | filters.SetPTS(VIDEO)
                t2 = split | filters.Trim(VIDEO, *second)
                p2 = t2 | filters.SetPTS(VIDEO)

                concat = p1 | filters.Concat(VIDEO)
                output = outputs.output_file('output.mp4',
                                             codecs.VideoCodec('libx264'))
                p2 | concat > output

                ff > output
                try:
                    ff.check_buffering()
                except BufferError as e:
                    self.assertTrue(raises, e)
                else:
                    self.assertFalse(raises)
Пример #11
0
    def test_fix_trim_buffering(self):
        """
        Trim buffering could be fixed with multiple source file deconding.
        """
        ff = FFMPEG()
        v1 = inputs.Stream(VIDEO, self.source.streams[0].meta)
        a1 = inputs.Stream(AUDIO, self.source.streams[1].meta)
        v2 = inputs.Stream(VIDEO, self.source.streams[0].meta)
        a2 = inputs.Stream(AUDIO, self.source.streams[1].meta)

        in1 = ff < inputs.input_file('input.mp4', v1, a1)
        in2 = ff < inputs.input_file('input.mp4', v2, a2)

        p1 = in1.video | filters.Trim(VIDEO, 2.0, 3.0) | filters.SetPTS(VIDEO)
        p2 = in2.video | filters.Trim(VIDEO, 1.0, 2.0) | filters.SetPTS(VIDEO)

        output = outputs.output_file('output.mp4',
                                     codecs.VideoCodec('libx264'))

        concat = p1 | filters.Concat(VIDEO)
        p2 | concat > output

        ff > output
        ff.check_buffering()