mirror of
https://github.com/kkroening/ffmpeg-python.git
synced 2025-04-06 04:15:44 +08:00
add header Node
This commit is contained in:
parent
78fb6cf2f1
commit
3f65898ac2
1
.gitignore
vendored
1
.gitignore
vendored
@ -6,3 +6,4 @@ ffmpeg/tests/sample_data/out*.mp4
|
|||||||
ffmpeg_python.egg-info/
|
ffmpeg_python.egg-info/
|
||||||
venv*
|
venv*
|
||||||
build/
|
build/
|
||||||
|
*pyc
|
5
.vscode/settings.json
vendored
Normal file
5
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"python.linting.pylintEnabled": false,
|
||||||
|
"python.linting.pep8Enabled": true,
|
||||||
|
"python.linting.enabled": true
|
||||||
|
}
|
@ -6,6 +6,7 @@ from ._utils import basestring
|
|||||||
from .nodes import (
|
from .nodes import (
|
||||||
filter_operator,
|
filter_operator,
|
||||||
GlobalNode,
|
GlobalNode,
|
||||||
|
HeaderNode,
|
||||||
InputNode,
|
InputNode,
|
||||||
MergeOutputsNode,
|
MergeOutputsNode,
|
||||||
OutputNode,
|
OutputNode,
|
||||||
@ -13,7 +14,7 @@ from .nodes import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def input(filename, **kwargs):
|
def input(filename, *stream, **kwargs):
|
||||||
"""Input file URL (ffmpeg ``-i`` option)
|
"""Input file URL (ffmpeg ``-i`` option)
|
||||||
|
|
||||||
Any supplied kwargs are passed to ffmpeg verbatim (e.g. ``t=20``,
|
Any supplied kwargs are passed to ffmpeg verbatim (e.g. ``t=20``,
|
||||||
@ -29,7 +30,13 @@ def input(filename, **kwargs):
|
|||||||
if 'format' in kwargs:
|
if 'format' in kwargs:
|
||||||
raise ValueError("Can't specify both `format` and `f` kwargs")
|
raise ValueError("Can't specify both `format` and `f` kwargs")
|
||||||
kwargs['format'] = fmt
|
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()
|
@output_operator()
|
||||||
@ -94,4 +101,4 @@ def output(*streams_and_filename, **kwargs):
|
|||||||
return OutputNode(streams, output.__name__, kwargs=kwargs).stream()
|
return OutputNode(streams, output.__name__, kwargs=kwargs).stream()
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['input', 'merge_outputs', 'output', 'overwrite_output']
|
__all__ = ['header', 'input', 'merge_outputs', 'output', 'overwrite_output']
|
||||||
|
@ -13,6 +13,7 @@ from .nodes import (
|
|||||||
get_stream_spec_nodes,
|
get_stream_spec_nodes,
|
||||||
FilterNode,
|
FilterNode,
|
||||||
GlobalNode,
|
GlobalNode,
|
||||||
|
HeaderNode,
|
||||||
InputNode,
|
InputNode,
|
||||||
OutputNode,
|
OutputNode,
|
||||||
output_operator,
|
output_operator,
|
||||||
@ -53,8 +54,8 @@ def _format_input_stream_name(stream_name_map, edge, is_final_arg=False):
|
|||||||
else:
|
else:
|
||||||
suffix = ':{}'.format(edge.upstream_selector)
|
suffix = ':{}'.format(edge.upstream_selector)
|
||||||
if is_final_arg and isinstance(edge.upstream_node, InputNode):
|
if is_final_arg and isinstance(edge.upstream_node, InputNode):
|
||||||
## Special case: `-map` args should not have brackets for input
|
# Special case: `-map` args should not have brackets for input
|
||||||
## nodes.
|
# nodes.
|
||||||
fmt = '{}{}'
|
fmt = '{}{}'
|
||||||
else:
|
else:
|
||||||
fmt = '[{}{}]'
|
fmt = '[{}{}]'
|
||||||
@ -153,12 +154,14 @@ def get_args(stream_spec, overwrite_output=False):
|
|||||||
args = []
|
args = []
|
||||||
# TODO: group nodes together, e.g. `-i somefile -r somerate`.
|
# TODO: group nodes together, e.g. `-i somefile -r somerate`.
|
||||||
sorted_nodes, outgoing_edge_maps = topo_sort(nodes)
|
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)]
|
input_nodes = [node for node in sorted_nodes if isinstance(node, InputNode)]
|
||||||
output_nodes = [node for node in sorted_nodes if isinstance(node, OutputNode)]
|
output_nodes = [node for node in sorted_nodes if isinstance(node, OutputNode)]
|
||||||
global_nodes = [node for node in sorted_nodes if isinstance(node, GlobalNode)]
|
global_nodes = [node for node in sorted_nodes if isinstance(node, GlobalNode)]
|
||||||
filter_nodes = [node for node in sorted_nodes if isinstance(node, FilterNode)]
|
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)}
|
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)
|
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])
|
args += reduce(operator.add, [_get_input_args(node) for node in input_nodes])
|
||||||
if filter_arg:
|
if filter_arg:
|
||||||
args += ['-filter_complex', filter_arg]
|
args += ['-filter_complex', filter_arg]
|
||||||
|
@ -235,7 +235,7 @@ class Node(KwargReprNode):
|
|||||||
class FilterableStream(Stream):
|
class FilterableStream(Stream):
|
||||||
def __init__(self, upstream_node, upstream_label, upstream_selector=None):
|
def __init__(self, upstream_node, upstream_label, upstream_selector=None):
|
||||||
super(FilterableStream, self).__init__(
|
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):
|
class InputNode(Node):
|
||||||
"""InputNode type"""
|
"""InputNode type"""
|
||||||
|
|
||||||
def __init__(self, name, args=[], kwargs={}):
|
def __init__(self, name, stream: Stream = None, args=[], kwargs={}):
|
||||||
super(InputNode, self).__init__(
|
super(InputNode, self).__init__(
|
||||||
stream_spec=None,
|
stream_spec=stream,
|
||||||
name=name,
|
name=name,
|
||||||
incoming_stream_types={},
|
incoming_stream_types={FilterableStream},
|
||||||
outgoing_stream_type=FilterableStream,
|
outgoing_stream_type=FilterableStream,
|
||||||
min_inputs=0,
|
min_inputs=0,
|
||||||
max_inputs=0,
|
max_inputs=0,
|
||||||
@ -343,6 +343,23 @@ class MergeOutputsNode(Node):
|
|||||||
|
|
||||||
|
|
||||||
# noinspection PyMethodOverriding
|
# 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):
|
class GlobalNode(Node):
|
||||||
def __init__(self, stream, name, args=[], kwargs={}):
|
def __init__(self, stream, name, args=[], kwargs={}):
|
||||||
super(GlobalNode, self).__init__(
|
super(GlobalNode, self).__init__(
|
||||||
|
@ -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():
|
def _get_simple_example():
|
||||||
return ffmpeg.input(TEST_INPUT_FILE1).output(TEST_OUTPUT_FILE1)
|
return ffmpeg.input(TEST_INPUT_FILE1).output(TEST_OUTPUT_FILE1)
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
alabaster==0.7.12
|
alabaster==0.7.12
|
||||||
atomicwrites==1.3.0
|
atomicwrites==1.3.0
|
||||||
attrs==19.1.0
|
attrs==19.1.0
|
||||||
|
autopep8==1.4.4
|
||||||
Babel==2.7.0
|
Babel==2.7.0
|
||||||
certifi==2019.3.9
|
certifi==2019.3.9
|
||||||
chardet==3.0.4
|
chardet==3.0.4
|
||||||
|
Loading…
x
Reference in New Issue
Block a user