def test_input_stream_naming(self): """ inputs.Input stream naming test.""" ff = self.ffmpeg ff < self.logo ff < self.source cv0 = self.video_codec ca0 = self.audio_codec overlay = filters.Overlay(0, 0) ff.video | filters.Scale(640, 360) | overlay ff.video | filters.Scale(1280, 720) | overlay ff.audio | Volume(-20) > ca0 overlay > cv0 ff > self.output self.assert_ffmpeg_args( '-i', 'logo.png', '-i', 'source.mp4', '-filter_complex', '[0:v]scale=w=640:h=360[v:scale0];' '[v:scale0][v:scale1]overlay[vout0];' '[1:v]scale=w=1280:h=720[v:scale1];' '[1:a]volume=-20.00[aout0]', '-map', '[vout0]', '-c:v', 'libx264', '-b:v', '3600000', '-map', '[aout0]', '-c:a', 'aac', '-b:a', '192000', 'output.mp4')
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_concat(self): """ Concat source files.""" ff = self.ffmpeg ff < self.preroll ff < self.source preroll_ready = ff.video | filters.Scale(640, 480) | SetSAR(1) concat = filters.Concat(VIDEO) preroll_ready | concat ff.video | concat concat > self.video_codec aconcat = filters.Concat(AUDIO) ff.audio | aconcat ff.audio | aconcat aconcat > self.audio_codec ff > self.output self.assert_ffmpeg_args( '-i', 'preroll.mp4', '-i', 'source.mp4', '-filter_complex', "[0:v]scale=w=640:h=480[v:scale0];" "[v:scale0]setsar=1[v:setsar0];" "[v:setsar0][1:v]concat[vout0];" "[0:a][1:a]concat=v=0:a=1:n=2[aout0]", '-map', '[vout0]', '-c:v', 'libx264', '-b:v', '3600000', '-map', '[aout0]', '-c:a', 'aac', '-b:a', '192000', 'output.mp4')
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_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')
def test_bypass_disabled_filter(self): """ Audio stream bypass mode.""" ff = self.ffmpeg ff < self.source scale = filters.Scale(640, 360) scale.enabled = False ff.video | scale > self.video_codec ff > self.output 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')
def test_bypass_with_filter_complex(self): """ Audio stream bypass mode.""" ff = self.ffmpeg ff < self.source ff.video | filters.Scale(640, 360) > self.video_codec ff > self.output self.assert_ffmpeg_args('-i', 'source.mp4', '-filter_complex', '[0:v]scale=w=640:h=360[vout0]', '-map', '[vout0]', '-c:v', 'libx264', '-b:v', '3600000', '-map', '0:a', '-c:a', 'aac', '-b:a', '192000', 'output.mp4')
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
def test_validate_input_hardware(self): """ Hardware-decoded input could not be passed to CPU codec and so on. """ vs = inputs.Stream(StreamType.VIDEO, meta=video_meta_data(width=640, height=360)) src = inputs.Input(streams=(vs, ), hardware='cuda', device='foo') @dataclass class X264(VideoCodec): codec = 'libx264' hardware = None # cpu only with self.assertRaises(ValueError): src.video > X264() with self.assertRaises(ValueError): src.video | filters.Scale(640, 360) src.video | ScaleNPP(640, 360) > H264Cuda()