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')
def test_ffmpeg(self): """ Smoke test and feature demo.""" ff = self.ffmpeg ff.loglevel = 'info' ff.realtime = True self.source.fast_seek = 123.2 self.source.duration = TS(321.2) ff < self.source cv0 = self.video_codec ca0 = self.audio_codec ca1 = codecs.AudioCodec('libmp3lame', bitrate=394000) asplit = self.source.audio | filters.Split(AUDIO) self.source.video | filters.Scale(640, 360) > cv0 asplit.connect_dest(ca0) asplit.connect_dest(ca1) out0 = self.output out1 = outputs.output_file('/tmp/out.mp3', ca1) ff > out0 ff > out1 self.assert_ffmpeg_args( '-loglevel', 'info', '-re', '-ss', '123.2', '-t', '321.2', '-i', 'source.mp4', '-filter_complex', '[0:v]scale=w=640:h=360[vout0];[0:a]asplit[aout0][aout1]', '-map', '[vout0]', '-c:v', 'libx264', '-b:v', '3600000', '-map', '[aout0]', '-c:a', 'aac', '-b:a', '192000', 'output.mp4', '-map', '[aout1]', '-c:a', 'libmp3lame', '-b:a', '394000', '-vn', '/tmp/out.mp3')
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', )
def test_codec_metadata_transform(self): """ Codecs parameters applied to stream metadata when using transform. """ with self.subTest('codec with transform'): self.source.audio > self.output am = cast(AudioMeta, self.output.codecs[1].meta) self.assertEqual(am.bitrate, self.target_audio_bitrate) with self.subTest('no input metadata'): no_meta_input = inputs.input_file('input.mp4') output = outputs.output_file('output.mp4', codecs.AudioCodec('aac')) no_meta_input.audio > output.audio self.assertIsNone(output.codecs[0].meta) with self.subTest('no transform'): output = outputs.output_file('output.mp4', codecs.AudioCodec('aac')) self.source.audio > output.audio am = cast(AudioMeta, output.codecs[0].meta) self.assertEqual(am.bitrate, self.audio_metadata.bitrate)
def test_handle_codec_copy(self): """ vcodec=copy connects source directly to muxer.""" ff = self.ffmpeg ff < self.source cv0 = codecs.Copy(kind=VIDEO) 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')
def setUp(self) -> None: self.video_metadata = meta.video_meta_data( width=1920, height=1080, dar=1.777777778, par=1.0, duration=300.0, ) self.audio_metadata = meta.audio_meta_data() 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( output_file='output.mp4', codecs=[H264Cuda(), codecs.AudioCodec('aac')])
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))
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)