From 3f65898ac26b14bf0252de7c8e19cf6283a4c7f8 Mon Sep 17 00:00:00 2001 From: Linus Date: Sat, 13 Jul 2019 04:44:28 +1200 Subject: [PATCH 1/9] add header Node --- .gitignore | 1 + .vscode/settings.json | 5 +++++ ffmpeg/_ffmpeg.py | 13 ++++++++++--- ffmpeg/_run.py | 7 +++++-- ffmpeg/nodes.py | 25 +++++++++++++++++++++---- ffmpeg/tests/test_ffmpeg.py | 16 +++++++++++++++- requirements.txt | 1 + 7 files changed, 58 insertions(+), 10 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.gitignore b/.gitignore index 780f20e..866cf60 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ ffmpeg/tests/sample_data/out*.mp4 ffmpeg_python.egg-info/ venv* build/ +*pyc \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..b5f2aa4 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "python.linting.pylintEnabled": false, + "python.linting.pep8Enabled": true, + "python.linting.enabled": true +} \ No newline at end of file diff --git a/ffmpeg/_ffmpeg.py b/ffmpeg/_ffmpeg.py index 31e2b90..fa3ae79 100644 --- a/ffmpeg/_ffmpeg.py +++ b/ffmpeg/_ffmpeg.py @@ -6,6 +6,7 @@ from ._utils import basestring from .nodes import ( filter_operator, GlobalNode, + HeaderNode, InputNode, MergeOutputsNode, OutputNode, @@ -13,7 +14,7 @@ from .nodes import ( ) -def input(filename, **kwargs): +def input(filename, *stream, **kwargs): """Input file URL (ffmpeg ``-i`` option) Any supplied kwargs are passed to ffmpeg verbatim (e.g. ``t=20``, @@ -29,7 +30,13 @@ def input(filename, **kwargs): if 'format' in kwargs: raise ValueError("Can't specify both `format` and `f` kwargs") kwargs['format'] = fmt - return InputNode(input.__name__, kwargs=kwargs).stream() + return InputNode(input.__name__, stream=stream, kwargs=kwargs).stream() + + +def header(**kwargs): + """Add extra header command-line argument(s), e.g. ``-re``. + """ + return HeaderNode(header.__name__, kwargs=kwargs).stream() @output_operator() @@ -94,4 +101,4 @@ def output(*streams_and_filename, **kwargs): return OutputNode(streams, output.__name__, kwargs=kwargs).stream() -__all__ = ['input', 'merge_outputs', 'output', 'overwrite_output'] +__all__ = ['header', 'input', 'merge_outputs', 'output', 'overwrite_output'] diff --git a/ffmpeg/_run.py b/ffmpeg/_run.py index afc504d..ac62720 100644 --- a/ffmpeg/_run.py +++ b/ffmpeg/_run.py @@ -13,6 +13,7 @@ from .nodes import ( get_stream_spec_nodes, FilterNode, GlobalNode, + HeaderNode, InputNode, OutputNode, output_operator, @@ -53,8 +54,8 @@ def _format_input_stream_name(stream_name_map, edge, is_final_arg=False): else: suffix = ':{}'.format(edge.upstream_selector) if is_final_arg and isinstance(edge.upstream_node, InputNode): - ## Special case: `-map` args should not have brackets for input - ## nodes. + # Special case: `-map` args should not have brackets for input + # nodes. fmt = '{}{}' else: fmt = '[{}{}]' @@ -153,12 +154,14 @@ def get_args(stream_spec, overwrite_output=False): args = [] # TODO: group nodes together, e.g. `-i somefile -r somerate`. sorted_nodes, outgoing_edge_maps = topo_sort(nodes) + header_nodes = [node for node in sorted_nodes if isinstance(node, HeaderNode)] input_nodes = [node for node in sorted_nodes if isinstance(node, InputNode)] output_nodes = [node for node in sorted_nodes if isinstance(node, OutputNode)] global_nodes = [node for node in sorted_nodes if isinstance(node, GlobalNode)] filter_nodes = [node for node in sorted_nodes if isinstance(node, FilterNode)] stream_name_map = {(node, None): str(i) for i, node in enumerate(input_nodes)} filter_arg = _get_filter_arg(filter_nodes, outgoing_edge_maps, stream_name_map) + args += reduce(operator.add, [_get_global_args(node) for node in header_nodes], []) args += reduce(operator.add, [_get_input_args(node) for node in input_nodes]) if filter_arg: args += ['-filter_complex', filter_arg] diff --git a/ffmpeg/nodes.py b/ffmpeg/nodes.py index cacab8e..9019bd3 100644 --- a/ffmpeg/nodes.py +++ b/ffmpeg/nodes.py @@ -235,7 +235,7 @@ class Node(KwargReprNode): class FilterableStream(Stream): def __init__(self, upstream_node, upstream_label, upstream_selector=None): super(FilterableStream, self).__init__( - upstream_node, upstream_label, {InputNode, FilterNode}, upstream_selector + upstream_node, upstream_label, {HeaderNode, InputNode, FilterNode}, upstream_selector ) @@ -243,11 +243,11 @@ class FilterableStream(Stream): class InputNode(Node): """InputNode type""" - def __init__(self, name, args=[], kwargs={}): + def __init__(self, name, stream: Stream = None, args=[], kwargs={}): super(InputNode, self).__init__( - stream_spec=None, + stream_spec=stream, name=name, - incoming_stream_types={}, + incoming_stream_types={FilterableStream}, outgoing_stream_type=FilterableStream, min_inputs=0, max_inputs=0, @@ -343,6 +343,23 @@ class MergeOutputsNode(Node): # noinspection PyMethodOverriding +class HeaderNode (Node): + + def __init__(self, name: str = None, args=[], kwargs={}): + super(HeaderNode, self).__init__( + stream_spec=None, + name=name, + incoming_stream_types={}, + outgoing_stream_type=FilterableStream, + min_inputs=0, + max_inputs=0, + args=args, + kwargs=kwargs, + ) + +# noinspection PyMethodOverriding + + class GlobalNode(Node): def __init__(self, stream, name, args=[], kwargs={}): super(GlobalNode, self).__init__( diff --git a/ffmpeg/tests/test_ffmpeg.py b/ffmpeg/tests/test_ffmpeg.py index 279a323..aecf069 100644 --- a/ffmpeg/tests/test_ffmpeg.py +++ b/ffmpeg/tests/test_ffmpeg.py @@ -135,6 +135,20 @@ def test_global_args(): ] +def test_header_args(): + out_file = ( + ffmpeg.header(thread_queue_size='512') + .input("input.mp4") + .output("output.mp4") + ) + assert out_file.get_args() == [ + '-thread_queue_size=512', + '-i', + 'input.mp4', + 'output.mp4', + ] + + def _get_simple_example(): return ffmpeg.input(TEST_INPUT_FILE1).output(TEST_OUTPUT_FILE1) @@ -697,7 +711,7 @@ def test_pipe(): out_data = p.stdout.read() assert len(out_data) == frame_size * (frame_count - start_frame) - assert out_data == in_data[start_frame * frame_size :] + assert out_data == in_data[start_frame * frame_size:] def test__probe(): diff --git a/requirements.txt b/requirements.txt index f8b347e..1034d9d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,7 @@ alabaster==0.7.12 atomicwrites==1.3.0 attrs==19.1.0 +autopep8==1.4.4 Babel==2.7.0 certifi==2019.3.9 chardet==3.0.4 From 76bc4179c6c05c2c998a1de7f7e1742d25c819d6 Mon Sep 17 00:00:00 2001 From: Linus Date: Sun, 14 Jul 2019 00:37:50 +1200 Subject: [PATCH 2/9] Handled header node --- ffmpeg/_ffmpeg.py | 19 ++++++++++++++----- ffmpeg/_run.py | 15 ++++++++++++++- ffmpeg/nodes.py | 4 ++-- ffmpeg/tests/test_ffmpeg.py | 8 +++++++- 4 files changed, 37 insertions(+), 9 deletions(-) diff --git a/ffmpeg/_ffmpeg.py b/ffmpeg/_ffmpeg.py index fa3ae79..2cbcf86 100644 --- a/ffmpeg/_ffmpeg.py +++ b/ffmpeg/_ffmpeg.py @@ -14,7 +14,8 @@ from .nodes import ( ) -def input(filename, *stream, **kwargs): +@filter_operator() +def input(*streams_and_filename, **kwargs): """Input file URL (ffmpeg ``-i`` option) Any supplied kwargs are passed to ffmpeg verbatim (e.g. ``t=20``, @@ -24,19 +25,27 @@ def input(filename, *stream, **kwargs): Official documentation: `Main options `__ """ - kwargs['filename'] = filename + streams_and_filename = list(streams_and_filename) + if 'filename' not in kwargs: + if not isinstance(streams_and_filename[-1], basestring): + raise ValueError('A filename must be provided') + kwargs['filename'] = streams_and_filename.pop(-1) + streams = streams_and_filename + fmt = kwargs.pop('f', None) if fmt: if 'format' in kwargs: raise ValueError("Can't specify both `format` and `f` kwargs") kwargs['format'] = fmt - return InputNode(input.__name__, stream=stream, kwargs=kwargs).stream() + return InputNode(name=input.__name__, stream=streams, kwargs=kwargs).stream() -def header(**kwargs): +def header(*args, **kwargs): """Add extra header command-line argument(s), e.g. ``-re``. """ - return HeaderNode(header.__name__, kwargs=kwargs).stream() + stream = None + print("in header: {}, {}, {}".format(repr(stream), args, kwargs)) + return HeaderNode(name=header.__name__, args=args, kwargs=kwargs).stream() @output_operator() diff --git a/ffmpeg/_run.py b/ffmpeg/_run.py index ac62720..a6f08de 100644 --- a/ffmpeg/_run.py +++ b/ffmpeg/_run.py @@ -107,6 +107,17 @@ def _get_filter_arg(filter_nodes, outgoing_edge_maps, stream_name_map): return ';'.join(filter_specs) +def _get_header_args(node): + kwargs = copy.copy(node.kwargs) + args = [] + print(node.args) + print(node.kwargs) + for arg in node.args: + args += arg + args += convert_kwargs_to_cmd_line_args(kwargs) + return args + + def _get_global_args(node): return list(node.args) @@ -155,13 +166,15 @@ def get_args(stream_spec, overwrite_output=False): # TODO: group nodes together, e.g. `-i somefile -r somerate`. sorted_nodes, outgoing_edge_maps = topo_sort(nodes) header_nodes = [node for node in sorted_nodes if isinstance(node, HeaderNode)] + + print('{}'.format(repr(header_nodes))) input_nodes = [node for node in sorted_nodes if isinstance(node, InputNode)] output_nodes = [node for node in sorted_nodes if isinstance(node, OutputNode)] global_nodes = [node for node in sorted_nodes if isinstance(node, GlobalNode)] filter_nodes = [node for node in sorted_nodes if isinstance(node, FilterNode)] stream_name_map = {(node, None): str(i) for i, node in enumerate(input_nodes)} filter_arg = _get_filter_arg(filter_nodes, outgoing_edge_maps, stream_name_map) - args += reduce(operator.add, [_get_global_args(node) for node in header_nodes], []) + args += reduce(operator.add, [_get_header_args(node) for node in header_nodes], []) args += reduce(operator.add, [_get_input_args(node) for node in input_nodes]) if filter_arg: args += ['-filter_complex', filter_arg] diff --git a/ffmpeg/nodes.py b/ffmpeg/nodes.py index 9019bd3..7a23814 100644 --- a/ffmpeg/nodes.py +++ b/ffmpeg/nodes.py @@ -198,6 +198,7 @@ class Node(KwargReprNode): kwargs={}, ): stream_map = get_stream_map(stream_spec) + print('{}'.format(stream_map)) self.__check_input_len(stream_map, min_inputs, max_inputs) self.__check_input_types(stream_map, incoming_stream_types) incoming_edge_map = self.__get_incoming_edge_map(stream_map) @@ -250,7 +251,7 @@ class InputNode(Node): incoming_stream_types={FilterableStream}, outgoing_stream_type=FilterableStream, min_inputs=0, - max_inputs=0, + max_inputs=None, args=args, kwargs=kwargs, ) @@ -342,7 +343,6 @@ class MergeOutputsNode(Node): ) -# noinspection PyMethodOverriding class HeaderNode (Node): def __init__(self, name: str = None, args=[], kwargs={}): diff --git a/ffmpeg/tests/test_ffmpeg.py b/ffmpeg/tests/test_ffmpeg.py index aecf069..58c2dd2 100644 --- a/ffmpeg/tests/test_ffmpeg.py +++ b/ffmpeg/tests/test_ffmpeg.py @@ -136,13 +136,19 @@ def test_global_args(): def test_header_args(): + + # header = ffmpeg.header('-re', '-s', thread_queue_size=512) + + # print('in test: {}'.format(repr(header))) + out_file = ( ffmpeg.header(thread_queue_size='512') .input("input.mp4") .output("output.mp4") ) assert out_file.get_args() == [ - '-thread_queue_size=512', + '-thread_queue_size', + '512', '-i', 'input.mp4', 'output.mp4', From ca31154cef511206991c8abcf472d71fbf9abdc2 Mon Sep 17 00:00:00 2001 From: Linus Date: Tue, 16 Jul 2019 22:47:39 +1200 Subject: [PATCH 3/9] Added Facebook Live Test case --- ffmpeg/_ffmpeg.py | 1 - ffmpeg/_run.py | 5 +--- ffmpeg/nodes.py | 1 - ffmpeg/tests/test_facebook.py | 45 +++++++++++++++++++++++++++++++++++ ffmpeg/tests/test_ffmpeg.py | 4 ---- 5 files changed, 46 insertions(+), 10 deletions(-) create mode 100644 ffmpeg/tests/test_facebook.py diff --git a/ffmpeg/_ffmpeg.py b/ffmpeg/_ffmpeg.py index 2cbcf86..19ac7f6 100644 --- a/ffmpeg/_ffmpeg.py +++ b/ffmpeg/_ffmpeg.py @@ -44,7 +44,6 @@ def header(*args, **kwargs): """Add extra header command-line argument(s), e.g. ``-re``. """ stream = None - print("in header: {}, {}, {}".format(repr(stream), args, kwargs)) return HeaderNode(name=header.__name__, args=args, kwargs=kwargs).stream() diff --git a/ffmpeg/_run.py b/ffmpeg/_run.py index a6f08de..8dfffc8 100644 --- a/ffmpeg/_run.py +++ b/ffmpeg/_run.py @@ -69,6 +69,7 @@ def _format_output_stream_name(stream_name_map, edge): def _get_filter_spec(node, outgoing_edge_map, stream_name_map): incoming_edges = node.incoming_edges outgoing_edges = get_outgoing_edges(node, outgoing_edge_map) + inputs = [ _format_input_stream_name(stream_name_map, edge) for edge in incoming_edges ] @@ -110,8 +111,6 @@ def _get_filter_arg(filter_nodes, outgoing_edge_maps, stream_name_map): def _get_header_args(node): kwargs = copy.copy(node.kwargs) args = [] - print(node.args) - print(node.kwargs) for arg in node.args: args += arg args += convert_kwargs_to_cmd_line_args(kwargs) @@ -131,7 +130,6 @@ def _get_output_args(node, stream_name_map): raise ValueError('Output node {} has no mapped streams'.format(node)) for edge in node.incoming_edges: - # edge = node.incoming_edges[0] stream_name = _format_input_stream_name( stream_name_map, edge, is_final_arg=True ) @@ -167,7 +165,6 @@ def get_args(stream_spec, overwrite_output=False): sorted_nodes, outgoing_edge_maps = topo_sort(nodes) header_nodes = [node for node in sorted_nodes if isinstance(node, HeaderNode)] - print('{}'.format(repr(header_nodes))) input_nodes = [node for node in sorted_nodes if isinstance(node, InputNode)] output_nodes = [node for node in sorted_nodes if isinstance(node, OutputNode)] global_nodes = [node for node in sorted_nodes if isinstance(node, GlobalNode)] diff --git a/ffmpeg/nodes.py b/ffmpeg/nodes.py index 7a23814..b7c3899 100644 --- a/ffmpeg/nodes.py +++ b/ffmpeg/nodes.py @@ -198,7 +198,6 @@ class Node(KwargReprNode): kwargs={}, ): stream_map = get_stream_map(stream_spec) - print('{}'.format(stream_map)) self.__check_input_len(stream_map, min_inputs, max_inputs) self.__check_input_types(stream_map, incoming_stream_types) incoming_edge_map = self.__get_incoming_edge_map(stream_map) diff --git a/ffmpeg/tests/test_facebook.py b/ffmpeg/tests/test_facebook.py new file mode 100644 index 0000000..83c3d17 --- /dev/null +++ b/ffmpeg/tests/test_facebook.py @@ -0,0 +1,45 @@ +from __future__ import unicode_literals +from builtins import bytes +from builtins import range +from builtins import str +import ffmpeg +import os +import pytest +import random +import re +import subprocess + +try: + import mock # python 2 +except ImportError: + from unittest import mock # python 3 + + def pip_to_facebook(stream_key: str): + """ Capture Facetime camera and screen in macOS and stream it to facebook + """ + facetime_camera_input = ( + ffmpeg + .input('FaceTime:1', format='avfoundation', pix_fmt='uyvy422', framerate=30, s='320x240', probesize='200M') + ) + + audio = facetime_camera_input.audio + + video = ( + ffmpeg + .header(thread_queue_size='512', vsync='2') + .input('1:1', format='avfoundation', + pix_fmt='uyvy422', framerate=30, probesize='200M') + .overlay(facetime_camera_input) + + ) + output = ( + ffmpeg + .output(video, audio, 'rtmps://live-api-s.facebook.com:443/rtmp/{}'.format(stream_key), vsync='2', s='1280x720', pix_fmt='yuv420p', video_bitrate='1500000', f='flv', + vcodec='libx264', preset='superfast', x264opts='keyint=15', g='30', ac='2', ar='48000', acodec="aac", audio_bitrate="128000") + ) + + output.overwrite_output().run() + + +def test_fluent_equality(): + pip_to_facebook('351682605501180?s_bl=1&s_ps=1&s_sml=1&s_sw=0&s_vt=api-s&a=AbzMoYVOuxBYwxs7') diff --git a/ffmpeg/tests/test_ffmpeg.py b/ffmpeg/tests/test_ffmpeg.py index 58c2dd2..90b0c3e 100644 --- a/ffmpeg/tests/test_ffmpeg.py +++ b/ffmpeg/tests/test_ffmpeg.py @@ -137,10 +137,6 @@ def test_global_args(): def test_header_args(): - # header = ffmpeg.header('-re', '-s', thread_queue_size=512) - - # print('in test: {}'.format(repr(header))) - out_file = ( ffmpeg.header(thread_queue_size='512') .input("input.mp4") From 8c1712972408fefbaae5f221ce070fa8ffe95492 Mon Sep 17 00:00:00 2001 From: wkchan Date: Sun, 21 Jul 2019 09:08:54 +1200 Subject: [PATCH 4/9] Update .gitignore Co-Authored-By: Karl Kroening --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 866cf60..39e48f3 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,4 @@ ffmpeg/tests/sample_data/out*.mp4 ffmpeg_python.egg-info/ venv* build/ -*pyc \ No newline at end of file +*.pyc From ba00ff8b687f977e90e9bf22fb84537787f8f871 Mon Sep 17 00:00:00 2001 From: Linus Date: Sun, 21 Jul 2019 09:14:06 +1200 Subject: [PATCH 5/9] Update test_facebook test case --- ffmpeg/tests/test_facebook.py | 65 ++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 28 deletions(-) diff --git a/ffmpeg/tests/test_facebook.py b/ffmpeg/tests/test_facebook.py index 83c3d17..9ac6cf0 100644 --- a/ffmpeg/tests/test_facebook.py +++ b/ffmpeg/tests/test_facebook.py @@ -1,45 +1,54 @@ from __future__ import unicode_literals -from builtins import bytes -from builtins import range -from builtins import str -import ffmpeg + import os -import pytest import random import re import subprocess +from builtins import bytes, range, str + +import ffmpeg +import pytest +from ffmpeg import nodes try: import mock # python 2 except ImportError: from unittest import mock # python 3 - def pip_to_facebook(stream_key: str): - """ Capture Facetime camera and screen in macOS and stream it to facebook - """ - facetime_camera_input = ( - ffmpeg - .input('FaceTime:1', format='avfoundation', pix_fmt='uyvy422', framerate=30, s='320x240', probesize='200M') - ) - audio = facetime_camera_input.audio +def pip_to_rtmp(url: str): + """ Capture Facetime camera and screen in macOS and stream it to facebook + """ + facetime_camera_input = ( + ffmpeg + .input('FaceTime:1', format='avfoundation', pix_fmt='uyvy422', framerate=30, s='320x240', probesize='200M') + ) - video = ( - ffmpeg - .header(thread_queue_size='512', vsync='2') - .input('1:1', format='avfoundation', - pix_fmt='uyvy422', framerate=30, probesize='200M') - .overlay(facetime_camera_input) + audio = facetime_camera_input.audio - ) - output = ( - ffmpeg - .output(video, audio, 'rtmps://live-api-s.facebook.com:443/rtmp/{}'.format(stream_key), vsync='2', s='1280x720', pix_fmt='yuv420p', video_bitrate='1500000', f='flv', - vcodec='libx264', preset='superfast', x264opts='keyint=15', g='30', ac='2', ar='48000', acodec="aac", audio_bitrate="128000") - ) + # ffmpeg in MacOS AVFoundation MUST increase the thread_queue_size in order to handle PIP + video = ( + ffmpeg + .header(thread_queue_size='512', vsync='2') + .input('1:1', format='avfoundation', + pix_fmt='uyvy422', framerate=30, probesize='200M') + .overlay(facetime_camera_input) - output.overwrite_output().run() + ) + output = ( + ffmpeg + .output(video, audio, url, vsync='2', s='1280x720', pix_fmt='yuv420p', video_bitrate='1500000', f='flv', + vcodec='libx264', preset='fast', x264opts='keyint=15', g='30', ac='2', ar='48000', acodec="aac", audio_bitrate="128000") + ) + + return output.overwrite_output().compile() -def test_fluent_equality(): - pip_to_facebook('351682605501180?s_bl=1&s_ps=1&s_sml=1&s_sw=0&s_vt=api-s&a=AbzMoYVOuxBYwxs7') +def test_rtmp(): + expected_result = ['ffmpeg', '-thread_queue_size', '512', '-vsync', '2', '-f', 'avfoundation', '-framerate', '30', '-pix_fmt', 'uyvy422', '-probesize', '200M', '-i', '1:1', '-f', 'avfoundation', '-framerate', '30', '-pix_fmt', 'uyvy422', '-probesize', '200M', '-s', '320x240', '-i', 'FaceTime:1', '-filter_complex', '[0][1]overlay=eof_action=repeat[s0]', + '-map', '[s0]', '-map', '1:a', '-f', 'flv', '-b:v', '1500000', '-b:a', '128000', '-ac', '2', '-acodec', 'aac', '-ar', '48000', '-g', '30', '-pix_fmt', 'yuv420p', '-preset', 'fast', '-s', '1280x720', '-vcodec', 'libx264', '-vsync', '2', '-x264opts', 'keyint=15', 'rtmps://live-api-s.facebook.com:443/rtmp/input_your_facebook_stream_key_here', '-y'] + # Your facebook key should look like: 123456789012345?s_bl=1&s_ps=1&s_sml=1&s_sw=0&s_vt=api-s&a=AbCdEfGhiJK12345 + your_facebook_key = 'input_your_facebook_stream_key_here' + facebook_stream_url = 'rtmps://live-api-s.facebook.com:443/rtmp/{}'.format(your_facebook_key) + result = pip_to_rtmp(facebook_stream_url) + assert result == expected_result From e742bfced262084835b68bb2691323638b392673 Mon Sep 17 00:00:00 2001 From: Linus Date: Sun, 21 Jul 2019 09:20:58 +1200 Subject: [PATCH 6/9] Update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 39e48f3..d20e29d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .cache .eggs .tox/ +.vscode/ dist/ ffmpeg/tests/sample_data/out*.mp4 ffmpeg_python.egg-info/ From 00a8f4f79a9a0ae36e34145b45b504cbfac84d20 Mon Sep 17 00:00:00 2001 From: Linus Date: Sun, 21 Jul 2019 09:25:33 +1200 Subject: [PATCH 7/9] remove "stream: " for matching with python 2.x syntax --- ffmpeg/nodes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ffmpeg/nodes.py b/ffmpeg/nodes.py index b7c3899..5ab3150 100644 --- a/ffmpeg/nodes.py +++ b/ffmpeg/nodes.py @@ -243,7 +243,7 @@ class FilterableStream(Stream): class InputNode(Node): """InputNode type""" - def __init__(self, name, stream: Stream = None, args=[], kwargs={}): + def __init__(self, name, Stream=None, args=[], kwargs={}): super(InputNode, self).__init__( stream_spec=stream, name=name, From 22c9cc2f03f6a8aea04284a87a3f107648a0f62e Mon Sep 17 00:00:00 2001 From: Linus Date: Sun, 21 Jul 2019 09:34:19 +1200 Subject: [PATCH 8/9] Fix stream paramater name --- ffmpeg/nodes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ffmpeg/nodes.py b/ffmpeg/nodes.py index 5ab3150..6da318b 100644 --- a/ffmpeg/nodes.py +++ b/ffmpeg/nodes.py @@ -243,7 +243,7 @@ class FilterableStream(Stream): class InputNode(Node): """InputNode type""" - def __init__(self, name, Stream=None, args=[], kwargs={}): + def __init__(self, name, stream, args=[], kwargs={}): super(InputNode, self).__init__( stream_spec=stream, name=name, From f839009802a786f4376d0b68bd799d5ecced8c7e Mon Sep 17 00:00:00 2001 From: Linus Date: Sun, 21 Jul 2019 09:39:01 +1200 Subject: [PATCH 9/9] match with python 2.x syntax --- ffmpeg/nodes.py | 2 +- ffmpeg/tests/test_facebook.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ffmpeg/nodes.py b/ffmpeg/nodes.py index 6da318b..d98b393 100644 --- a/ffmpeg/nodes.py +++ b/ffmpeg/nodes.py @@ -344,7 +344,7 @@ class MergeOutputsNode(Node): class HeaderNode (Node): - def __init__(self, name: str = None, args=[], kwargs={}): + def __init__(self, name, args=[], kwargs={}): super(HeaderNode, self).__init__( stream_spec=None, name=name, diff --git a/ffmpeg/tests/test_facebook.py b/ffmpeg/tests/test_facebook.py index 9ac6cf0..a670912 100644 --- a/ffmpeg/tests/test_facebook.py +++ b/ffmpeg/tests/test_facebook.py @@ -16,7 +16,7 @@ except ImportError: from unittest import mock # python 3 -def pip_to_rtmp(url: str): +def pip_to_rtmp(url): """ Capture Facetime camera and screen in macOS and stream it to facebook """ facetime_camera_input = (