mirror of https://github.com/streamlink/streamlink
Clean up RTMP and subprocess options a bit.
Also add --rtmp-timeout option.
This commit is contained in:
parent
35ec9e7b04
commit
e31c5c3c3a
57
docs/cli.rst
57
docs/cli.rst
|
@ -458,42 +458,32 @@ File output options
|
|||
Stream transport options
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. cmdoption:: -c, --cmdline
|
||||
|
||||
Print command-line used internally to play stream,
|
||||
this may not be available on all streams
|
||||
|
||||
.. cmdoption:: -e, --errorlog
|
||||
|
||||
Log possible errors from internal command-line to a
|
||||
temporary file, use when debugging
|
||||
|
||||
.. cmdoption:: -r path, --rtmpdump path
|
||||
|
||||
Specify location of rtmpdump executable, e.g.
|
||||
``/usr/local/bin/rtmpdump``
|
||||
|
||||
.. cmdoption:: --rtmpdump-proxy host:port
|
||||
|
||||
Specify a proxy (SOCKS) that rtmpdump will use
|
||||
|
||||
.. cmdoption:: --hls-live-edge segments
|
||||
|
||||
How many segments from the end to start live streams
|
||||
on, default is ``3``
|
||||
|
||||
.. versionadded:: 1.8.0
|
||||
|
||||
.. cmdoption:: --hls-segment-attempts attempts
|
||||
|
||||
How many attempts should be done to download each
|
||||
segment, default is ``3``
|
||||
|
||||
.. versionadded:: 1.8.0
|
||||
|
||||
.. cmdoption:: --hls-segment-timeout timeout
|
||||
|
||||
Segment connect and read timeout, default is ``10.0``
|
||||
|
||||
.. versionadded:: 1.8.0
|
||||
|
||||
.. cmdoption:: --hls-timeout timeout
|
||||
|
||||
HLS read timeout, default is ``60.0``
|
||||
Timeout for reading data from HLS streams,
|
||||
default is ``60.0``
|
||||
|
||||
.. versionadded:: 1.8.0
|
||||
|
||||
.. cmdoption:: --hds-live-edge seconds
|
||||
|
||||
|
@ -514,6 +504,33 @@ Stream transport options
|
|||
HDS streams manages this value automatically, use
|
||||
``--hds-fragment-buffer`` to change it
|
||||
|
||||
.. cmdoption:: --rtmp-proxy host:port, --rtmpdump-proxy host:port
|
||||
|
||||
Specify a proxy (SOCKS) that RTMP streams will use
|
||||
|
||||
.. cmdoption:: --rtmp-rtmpdump path, --rtmpdump path, -r path
|
||||
|
||||
Specify location of the rtmpdump executable used by
|
||||
RTMP streams, e.g. ``/usr/local/bin/rtmpdump``
|
||||
|
||||
.. cmdoption:: --rtmp-timeout timeout
|
||||
|
||||
Timeout for reading data from RTMP streams,
|
||||
default is ``60.0``
|
||||
|
||||
.. versionadded:: 1.8.0
|
||||
|
||||
.. cmdoption:: --subprocess-cmdline, --cmdline, -c
|
||||
|
||||
Print command-line used internally to play stream,
|
||||
this is only available for RTMP streams
|
||||
|
||||
.. cmdoption:: --subprocess-errorlog, --errorlog, -e
|
||||
|
||||
Log possible errors from internal subprocesses to a
|
||||
temporary file, use when debugging rtmpdump related
|
||||
issues
|
||||
|
||||
|
||||
Plugin options
|
||||
^^^^^^^^^^^^^^
|
||||
|
|
|
@ -39,16 +39,17 @@ class Livestreamer(object):
|
|||
def __init__(self):
|
||||
self.http = api.HTTPSession()
|
||||
self.options = Options({
|
||||
"rtmpdump": is_win32 and "rtmpdump.exe" or "rtmpdump",
|
||||
"rtmpdump-proxy": None,
|
||||
"ringbuffer-size": 1024 * 1024 * 16, # 16 MB
|
||||
"hds-live-edge": 10.0,
|
||||
"hds-fragment-buffer": 10,
|
||||
"hls-live-edge": 3,
|
||||
"hls-segment-attempts": 3,
|
||||
"hls-segment-timeout": 10.0,
|
||||
"hls-timeout": 60.0,
|
||||
"errorlog": False,
|
||||
"rtmp-timeout": 60.0,
|
||||
"rtmp-rtmpdump": is_win32 and "rtmpdump.exe" or "rtmpdump",
|
||||
"rtmp-proxy": None,
|
||||
"ringbuffer-size": 1024 * 1024 * 16, # 16 MB
|
||||
"subprocess-errorlog": False
|
||||
})
|
||||
self.plugins = {}
|
||||
self.logger = Logger()
|
||||
|
@ -65,9 +66,6 @@ class Livestreamer(object):
|
|||
**Available options**:
|
||||
|
||||
======================= =========================================
|
||||
errorlog (bool) Log errors from subprocesses to
|
||||
a file located in the temp directory
|
||||
|
||||
hls-live-edge (int) How many segments from the end
|
||||
to start live streams on, default: ``3``
|
||||
|
||||
|
@ -77,7 +75,8 @@ class Livestreamer(object):
|
|||
hls-segment-timeout (float) Segment connect and read timeout,
|
||||
default: ``10.0``
|
||||
|
||||
hls-timeout (float) HLS read timeout, default: ``60.0``
|
||||
hls-timeout (float) Timeout for reading data from
|
||||
HLS streams, default: ``60.0``
|
||||
|
||||
hds-fragment-buffer (int) Specify the maximum amount of
|
||||
fragments to buffer, this controls the
|
||||
|
@ -119,19 +118,36 @@ class Livestreamer(object):
|
|||
can be either a .pem file (str) or a
|
||||
.crt/.key pair (tuple)
|
||||
|
||||
subprocess-errorlog (bool) Log errors from subprocesses to
|
||||
a file located in the temp directory
|
||||
|
||||
ringbuffer-size (int) The size of the internal ring
|
||||
buffer used by most stream types,
|
||||
default: ``16777216`` (16MB)
|
||||
|
||||
rtmpdump (str) Specify the location of the
|
||||
rtmpdump executable, e.g.
|
||||
``/usr/local/bin/rtmpdump``
|
||||
rtmp-proxy (str) Specify a proxy (SOCKS) that RTMP
|
||||
streams will use
|
||||
|
||||
rtmp-rtmpdump (str) Specify the location of the
|
||||
rtmpdump executable used by RTMP streams,
|
||||
e.g. ``/usr/local/bin/rtmpdump``
|
||||
|
||||
rtmp-timeout (float) Timeout for reading data from
|
||||
RTMP streams, default: ``60.0``
|
||||
|
||||
|
||||
rtmpdump-proxy (str) Specify a proxy (SOCKS) that
|
||||
rtmpdump will use
|
||||
======================= =========================================
|
||||
|
||||
"""
|
||||
|
||||
# Backwards compatibility
|
||||
if key == "rtmpdump":
|
||||
key = "rtmp-rtmpdump"
|
||||
elif key == "rtmpdump-proxy":
|
||||
key = "rtmp-proxy"
|
||||
elif key == "errorlog":
|
||||
key = "subprocess-errorlog"
|
||||
|
||||
if key == "http-proxy":
|
||||
if not re.match("^http(s)?://", value):
|
||||
value = "http://" + value
|
||||
|
|
|
@ -9,8 +9,7 @@ from time import sleep
|
|||
import re
|
||||
|
||||
class RTMPStream(StreamProcess):
|
||||
"""
|
||||
RTMP stream handler using rtmpdump.
|
||||
"""RTMP stream using rtmpdump.
|
||||
|
||||
*Attributes:*
|
||||
|
||||
|
@ -19,24 +18,23 @@ class RTMPStream(StreamProcess):
|
|||
|
||||
__shortname__ = "rtmp"
|
||||
|
||||
def __init__(self, session, params, redirect=False, timeout=30):
|
||||
StreamProcess.__init__(self, session, params, timeout)
|
||||
def __init__(self, session, params, redirect=False):
|
||||
StreamProcess.__init__(self, session, params)
|
||||
|
||||
self.cmd = self.session.options.get("rtmpdump")
|
||||
self.cmd = self.session.options.get("rtmp-rtmpdump")
|
||||
self.timeout = self.session.options.get("rtmp-timeout")
|
||||
self.redirect = redirect
|
||||
self.logger = session.logger.new_module("stream.rtmp")
|
||||
|
||||
def __repr__(self):
|
||||
return ("<RTMPStream({0!r}, redirect={1!r}, "
|
||||
"timeout={2!r})>").format(self.params, self.redirect,
|
||||
self.timeout)
|
||||
return ("<RTMPStream({0!r}, redirect={1!r}>").format(self.params,
|
||||
self.redirect)
|
||||
|
||||
def __json__(self):
|
||||
return dict(type=RTMPStream.shortname(),
|
||||
params=self.params)
|
||||
return dict(type=RTMPStream.shortname(), params=self.params)
|
||||
|
||||
def open(self):
|
||||
if self.session.options.get("rtmpdump-proxy"):
|
||||
if self.session.options.get("rtmp-proxy"):
|
||||
if not self._supports_param("socks"):
|
||||
raise StreamError("Installed rtmpdump does not support --socks argument")
|
||||
|
||||
|
@ -111,9 +109,10 @@ class RTMPStream(StreamProcess):
|
|||
try:
|
||||
help = cmd(help=True, _err_to_out=True)
|
||||
except sh.ErrorReturnCode as err:
|
||||
raise StreamError(("Error while checking rtmpdump compatibility: {0}").format(str(err.stdout, "ascii")))
|
||||
err = str(err.stdout, "ascii")
|
||||
raise StreamError("Error while checking rtmpdump compatibility: {0}".format(err))
|
||||
|
||||
for line in help.split("\n"):
|
||||
for line in help.splitlines():
|
||||
m = re.match("^--(\w+)", line)
|
||||
|
||||
if not m:
|
||||
|
|
|
@ -26,14 +26,14 @@ class StreamProcessIO(StreamIOThreadWrapper):
|
|||
|
||||
|
||||
class StreamProcess(Stream):
|
||||
def __init__(self, session, params=None, timeout=30):
|
||||
def __init__(self, session, params=None, timeout=60.0):
|
||||
Stream.__init__(self, session)
|
||||
|
||||
if not params:
|
||||
params = {}
|
||||
|
||||
self.params = params
|
||||
self.errorlog = self.session.options.get("errorlog")
|
||||
self.errorlog = self.session.options.get("subprocess-errorlog")
|
||||
self.timeout = timeout
|
||||
|
||||
def open(self):
|
||||
|
@ -58,7 +58,8 @@ class StreamProcess(Stream):
|
|||
|
||||
if not process_alive:
|
||||
if self.errorlog:
|
||||
raise StreamError(("Error while executing subprocess, error output logged to: {0}").format(tmpfile.name))
|
||||
raise StreamError(("Error while executing subprocess, "
|
||||
"error output logged to: {0}").format(tmpfile.name))
|
||||
else:
|
||||
raise StreamError("Error while executing subprocess")
|
||||
|
||||
|
@ -69,7 +70,7 @@ class StreamProcess(Stream):
|
|||
try:
|
||||
cmd = sh.create_command(self.cmd)
|
||||
except sh.CommandNotFound as err:
|
||||
raise StreamError(("Unable to find {0} command").format(str(err)))
|
||||
raise StreamError("Unable to find {0} command".format(err))
|
||||
|
||||
return cmd
|
||||
|
||||
|
|
|
@ -170,18 +170,6 @@ outputopt.add_argument("-O", "--stdout", action="store_true",
|
|||
help="Write stream to stdout instead of playing it")
|
||||
|
||||
streamopt = parser.add_argument_group("stream transport options")
|
||||
streamopt.add_argument("-c", "--cmdline", action="store_true",
|
||||
help="Print command-line used internally to play "
|
||||
"stream, this may not be available on all streams")
|
||||
streamopt.add_argument("-e", "--errorlog", action="store_true",
|
||||
help="Log possible errors from internal command-line "
|
||||
"to a temporary file, use when debugging rtmpdump "
|
||||
"related issues")
|
||||
streamopt.add_argument("-r", "--rtmpdump", metavar="path",
|
||||
help="Specify location of rtmpdump executable, "
|
||||
"e.g. /usr/local/bin/rtmpdump")
|
||||
streamopt.add_argument("--rtmpdump-proxy", metavar="host:port",
|
||||
help="Specify a proxy (SOCKS) that rtmpdump will use")
|
||||
streamopt.add_argument("--hls-live-edge", type=int, metavar="segments",
|
||||
help="How many segments from the end to start "
|
||||
"live streams on, default is 3")
|
||||
|
@ -191,7 +179,9 @@ streamopt.add_argument("--hls-segment-attempts", type=int, metavar="attempts",
|
|||
streamopt.add_argument("--hls-segment-timeout", type=float, metavar="timeout",
|
||||
help="Segment connect and read timeout, default is 10.0")
|
||||
streamopt.add_argument("--hls-timeout", type=float, metavar="timeout",
|
||||
help="HLS read timeout, default is 60.0")
|
||||
help="Timeout for reading data from HLS streams, "
|
||||
"default is 60.0")
|
||||
|
||||
streamopt.add_argument("--hds-live-edge", type=float, metavar="seconds",
|
||||
help="Specify the time live HDS streams will start "
|
||||
"from the edge of stream, default is 10.0")
|
||||
|
@ -204,6 +194,23 @@ streamopt.add_argument("--ringbuffer-size", metavar="size", type=int,
|
|||
"ringbuffer, default is 16777216 (16MB). "
|
||||
"HDS streams manages this value automatically, "
|
||||
"use --hds-fragment-buffer to change it")
|
||||
streamopt.add_argument("--rtmp-proxy", "--rtmpdump-proxy", metavar="host:port",
|
||||
help="Specify a proxy (SOCKS) that RTMP streams will use")
|
||||
streamopt.add_argument("--rtmp-rtmpdump", "--rtmpdump", "-r", metavar="path",
|
||||
help="Specify location of the rtmpdump executable "
|
||||
"used by RTMP streams, e.g. /usr/local/bin/rtmpdump")
|
||||
streamopt.add_argument("--rtmp-timeout", type=float, metavar="timeout",
|
||||
help="Timeout for reading data from RTMP streams, "
|
||||
"default is 60.0")
|
||||
streamopt.add_argument("--subprocess-cmdline", "--cmdline", "-c",
|
||||
action="store_true",
|
||||
help="Print command-line used internally to play "
|
||||
"stream, this is only available for RTMP streams")
|
||||
streamopt.add_argument("--subprocess-errorlog", "--errorlog", "-e",
|
||||
action="store_true",
|
||||
help="Log possible errors from internal subprocesses "
|
||||
"to a temporary file, use when debugging rtmpdump "
|
||||
"related issues")
|
||||
|
||||
pluginopt = parser.add_argument_group("plugin options")
|
||||
pluginopt.add_argument("--plugin-dirs", metavar="directory", type=comma_list,
|
||||
|
|
|
@ -326,7 +326,7 @@ def handle_stream(plugin, streams, stream_name):
|
|||
|
||||
# Print internal command-line if this stream
|
||||
# uses a subprocess.
|
||||
if args.cmdline:
|
||||
if args.subprocess_cmdline:
|
||||
if isinstance(stream, StreamProcess):
|
||||
try:
|
||||
cmdline = stream.cmdline()
|
||||
|
@ -568,7 +568,7 @@ def setup_console():
|
|||
console.set_output(sys.stderr)
|
||||
|
||||
# We don't want log output when we are printing JSON or a command-line.
|
||||
if not (args.json or args.cmdline or args.quiet):
|
||||
if not (args.json or args.subprocess_cmdline or args.quiet):
|
||||
console.set_level(args.loglevel)
|
||||
|
||||
if args.quiet_player:
|
||||
|
@ -630,15 +630,6 @@ def setup_livestreamer():
|
|||
|
||||
def setup_options():
|
||||
"""Sets Livestreamer options."""
|
||||
|
||||
livestreamer.set_option("errorlog", args.errorlog)
|
||||
|
||||
if args.rtmpdump:
|
||||
livestreamer.set_option("rtmpdump", args.rtmpdump)
|
||||
|
||||
if args.rtmpdump_proxy:
|
||||
livestreamer.set_option("rtmpdump-proxy", args.rtmpdump_proxy)
|
||||
|
||||
if args.hls_live_edge:
|
||||
livestreamer.set_option("hls-live-edge", args.hls_live_edge)
|
||||
|
||||
|
@ -661,6 +652,20 @@ def setup_options():
|
|||
if args.ringbuffer_size:
|
||||
livestreamer.set_option("ringbuffer-size", args.ringbuffer_size)
|
||||
|
||||
if args.rtmp_proxy:
|
||||
livestreamer.set_option("rtmp-proxy", args.rtmp_proxy)
|
||||
|
||||
if args.rtmp_rtmpdump:
|
||||
livestreamer.set_option("rtmp-rtmpdump", args.rtmp_rtmpdump)
|
||||
|
||||
if args.rtmp_timeout:
|
||||
livestreamer.set_option("rtmp-timeout", args.rtmp_timeout)
|
||||
|
||||
livestreamer.set_option("subprocess-errorlog", args.subprocess_errorlog)
|
||||
|
||||
|
||||
def setup_plugin_options():
|
||||
"""Sets Livestreamer plugin options."""
|
||||
if args.jtv_cookie:
|
||||
livestreamer.set_plugin_option("justintv", "cookie",
|
||||
args.jtv_cookie)
|
||||
|
@ -767,6 +772,7 @@ def main():
|
|||
elif args.url:
|
||||
with ignored(KeyboardInterrupt):
|
||||
setup_options()
|
||||
setup_plugin_options()
|
||||
handle_url()
|
||||
elif args.twitch_oauth_authenticate:
|
||||
authenticate_twitch_oauth()
|
||||
|
|
Loading…
Reference in New Issue