def test_copy_codec_filter_forbidden(self): """ Copy codec must use a stream as source, not a filter from graph. """ with self.assertRaises(ValueError): self.source.video | Scale(1920, 1080) > codecs.Copy(kind=VIDEO) self.assertIsInstance(self.source.video > codecs.Copy(kind=VIDEO), codecs.Copy)
def test_copy_codec_kind_required(self): """ As codec is initially added to output file, it's kind is required. """ with self.assertRaises(NotImplementedError): codecs.Copy() self.assertEqual(codecs.Copy(kind=VIDEO).kind, VIDEO) self.assertEqual(codecs.Copy(kind=AUDIO).kind, AUDIO)
def test_copy_codec_transient_filter_forbidden(self): """ Copy codec must use a stream as a source, even if temporarily connected to a split filter. """ with self.assertRaises(ValueError): chain = self.source.video | Scale(1920, 1080) | Split(VIDEO) chain > codecs.Copy(kind=VIDEO) chain = self.source.video | Split(VIDEO) self.assertIsInstance(chain > codecs.Copy(kind=VIDEO), codecs.Copy)
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.Copy(kind=VIDEO) ca1 = codecs.Copy(kind=AUDIO) 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_handle_codec_copy_with_other_filters(self): """ vcodec=copy with separate transcoded output.""" ff = self.ffmpeg ff < self.source cv0 = codecs.Copy(kind=VIDEO) ca0 = codecs.Copy(kind=AUDIO) 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_split_disconnect_on_single_output(self): """ Transitive split disconnection on copy codec. """ split = self.source.video | Split(VIDEO, output_count=2) s2 = split | Split(VIDEO, output_count=1) s = Scale(1920, 1080) split | s s2 > codecs.Copy(kind=VIDEO) # s2 is now zero-output, so it's also disconnected from split. self.assertListEqual(split.outputs, [s.input])
def test_split_disconnect_on_copy_codec(self): """ Split can remove output edge from itself. """ split = self.source.video | Split(VIDEO, output_count=2) s1 = split s2 = split | Scale(1920, 1080) s1 > codecs.Copy(kind=VIDEO) # one output left self.assertListEqual(split.outputs, [s2.input]) # split is disabled because of single output self.assertFalse(split.enabled)
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')