parent
3ca11792cc
commit
468a3f2baf
2 changed files with 0 additions and 155 deletions
@ -1,140 +0,0 @@ |
||||
#!/usr/bin/env python |
||||
|
||||
from __future__ import print_function |
||||
|
||||
import sys |
||||
|
||||
import gi |
||||
|
||||
from gi.repository import GObject as gobject, Gst as gst |
||||
from streamlink import Streamlink, StreamError, PluginError, NoPluginError |
||||
|
||||
|
||||
def exit(msg): |
||||
print(msg, file=sys.stderr) |
||||
sys.exit() |
||||
|
||||
|
||||
class StreamlinkPlayer(object): |
||||
def __init__(self): |
||||
self.fd = None |
||||
self.mainloop = gobject.MainLoop() |
||||
|
||||
# This creates a playbin pipeline and using the appsrc source |
||||
# we can feed it our stream data |
||||
self.pipeline = gst.ElementFactory.make("playbin", None) |
||||
self.pipeline.set_property("uri", "appsrc://") |
||||
|
||||
# When the playbin creates the appsrc source it will call |
||||
# this callback and allow us to configure it |
||||
self.pipeline.connect("source-setup", self.on_source_setup) |
||||
|
||||
# Creates a bus and set callbacks to receive errors |
||||
self.bus = self.pipeline.get_bus() |
||||
self.bus.add_signal_watch() |
||||
self.bus.connect("message::eos", self.on_eos) |
||||
self.bus.connect("message::error", self.on_error) |
||||
|
||||
def exit(self, msg): |
||||
self.stop() |
||||
exit(msg) |
||||
|
||||
def stop(self): |
||||
# Stop playback and exit mainloop |
||||
self.pipeline.set_state(gst.State.NULL) |
||||
self.mainloop.quit() |
||||
|
||||
# Close the stream |
||||
if self.fd: |
||||
self.fd.close() |
||||
|
||||
def play(self, stream): |
||||
# Attempt to open the stream |
||||
try: |
||||
self.fd = stream.open() |
||||
except StreamError as err: |
||||
self.exit("Failed to open stream: {0}".format(err)) |
||||
|
||||
# Start playback |
||||
self.pipeline.set_state(gst.State.PLAYING) |
||||
self.mainloop.run() |
||||
|
||||
def on_source_setup(self, element, source): |
||||
# When this callback is called the appsrc expects |
||||
# us to feed it more data |
||||
source.connect("need-data", self.on_source_need_data) |
||||
|
||||
def on_source_need_data(self, source, length): |
||||
# Attempt to read data from the stream |
||||
try: |
||||
data = self.fd.read(length) |
||||
except IOError as err: |
||||
self.exit("Failed to read data from stream: {0}".format(err)) |
||||
|
||||
# If data is empty it's the end of stream |
||||
if not data: |
||||
source.emit("end-of-stream") |
||||
return |
||||
|
||||
# Convert the Python bytes into a GStreamer Buffer |
||||
# and then push it to the appsrc |
||||
buf = gst.Buffer.new_wrapped(data) |
||||
source.emit("push-buffer", buf) |
||||
|
||||
def on_eos(self, bus, msg): |
||||
# Stop playback on end of stream |
||||
self.stop() |
||||
|
||||
def on_error(self, bus, msg): |
||||
# Print error message and exit on error |
||||
error = msg.parse_error()[1] |
||||
self.exit(error) |
||||
|
||||
|
||||
def main(): |
||||
if len(sys.argv) < 3: |
||||
exit("Usage: {0} <url> <quality>".format(sys.argv[0])) |
||||
|
||||
# Initialize and check GStreamer version |
||||
gi.require_version("Gst", "1.0") |
||||
gobject.threads_init() |
||||
gst.init(None) |
||||
|
||||
# Collect arguments |
||||
url = sys.argv[1] |
||||
quality = sys.argv[2] |
||||
|
||||
# Create the Streamlink session |
||||
streamlink = Streamlink() |
||||
|
||||
# Enable logging |
||||
streamlink.set_loglevel("info") |
||||
streamlink.set_logoutput(sys.stdout) |
||||
|
||||
# Attempt to fetch streams |
||||
try: |
||||
streams = streamlink.streams(url) |
||||
except NoPluginError: |
||||
exit("Streamlink is unable to handle the URL '{0}'".format(url)) |
||||
except PluginError as err: |
||||
exit("Plugin error: {0}".format(err)) |
||||
|
||||
if not streams: |
||||
exit("No streams found on URL '{0}'".format(url)) |
||||
|
||||
# Look for specified stream |
||||
if quality not in streams: |
||||
exit("Unable to find '{0}' stream on URL '{1}'".format(quality, url)) |
||||
|
||||
# We found the stream |
||||
stream = streams[quality] |
||||
|
||||
# Create the player and start playback |
||||
player = StreamlinkPlayer() |
||||
|
||||
# Blocks until playback is done |
||||
player.play(stream) |
||||
|
||||
|
||||
if __name__ == "__main__": |
||||
main() |
Loading…
Reference in new issue