-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathreceptor.py
132 lines (92 loc) · 3.83 KB
/
receptor.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import sys
import wx
import os
import gi
import time
import signal
gi.require_version('Gst', '1.0')
gi.require_version('GstVideo', '1.0')
from gi.repository import Gst
from gi.repository import GstVideo
from gi.repository import GObject
from gi.repository import GLib
Gst.init(None)
class Receptor( wx.App ):
def OnInit(self):
window = wx.Frame(None)
window.SetTitle("Reproductor")
window.SetSize((640,480))
window.Bind(wx.EVT_CLOSE, self.quit)
self.SetTopWindow(window)
video_window = wx.Panel(window)
self.X_id = video_window.GetHandle()
window.Layout()
window.Show()
# Preparamos la información relativa a la ventana
self.puerto = int(sys.argv[1])
self.decoder = int(sys.argv[2])
# Creamos el Pipeline para Gstreamer
self.pipeline = Gst.Pipeline.new()
# Creamos el bus, que trata los eventos del pipeline.
self.bus = self.pipeline.get_bus()
self.bus.add_signal_watch()
self.bus.enable_sync_message_emission()
self.bus.connect('message::error', self.on_error)
self.bus.connect('sync-message::element', self.on_sync_message)
# Definimos los elementos que añadiremos al pipeline. Receptor.
self.udpsrc = Gst.ElementFactory.make('udpsrc', None) # La fuente recibida por UDP. Primera parte del pipeline.
self.vc = Gst.ElementFactory.make('videoconvert', None) # Cambia el espacio de color del video.
self.buffer = Gst.ElementFactory.make('rtpjitterbuffer', None) # Buffer que nos permite solucionar algunos problemas de inestabilidad de la red.
self.sink = Gst.ElementFactory.make('autovideosink', None) # Recibe los datos y los muestra.
self.udpsrc.set_property("port", self.puerto)
if self.decoder == 0:
self.depay = Gst.ElementFactory.make('rtph264depay', None)
self.decodebin = Gst.ElementFactory.make('avdec_h264', None)
cadena = "application/x-rtp, media=(string)video, clock-rate=(int)90000, decoding-name=(string)h264, payload=(int)96"
elif self.decoder == 1:
self.depay = Gst.ElementFactory.make('rtph265depay', None)
self.decodebin = Gst.ElementFactory.make('avdec_h265', None)
cadena = "application/x-rtp, media=(string)video, clock-rate=(int)90000, decoding-name=(string)h265, payload=(int)96"
else:
print("ERROR: Decoder selection not valid.")
sys.exit(1)
if(not self.pipeline or not self.udpsrc or not self.depay or not self.vc or not self.sink or not self.decodebin or not self.buffer):
print("ERROR: Could not create all elements")
sys.exit(1)
# Añadimos los elementos al pipeline.
self.pipeline.add(self.udpsrc)
self.pipeline.add(self.depay)
self.pipeline.add(self.vc)
self.pipeline.add(self.decodebin)
self.pipeline.add(self.sink)
self.pipeline.add(self.buffer)
if not self.udpsrc.link_filtered(self.buffer, Gst.caps_from_string(cadena)):
print("ERROR: Could not link 'udpsrc' to buffer")
if not self.buffer.link(self.depay):
print("ERROR: Could not link 'buffer' to depay")
if not self.depay.link(self.decodebin):
print("ERROR: Could not link 'depay' to decodebin")
if not self.decodebin.link(self.vc):
print("ERROR: Could not link 'decodebin' to vc")
if not self.vc.link(self.sink):
print("ERROR: Could not link 'vc' to sink")
ret = self.pipeline.set_state(Gst.State.PLAYING)
if ret == Gst.StateChangeReturn.FAILURE:
print("ERROR: Unable to set the pipeline to the playing state")
return False
return True
def on_sync_message(self, bus, message):
if message.get_structure() is None:
return True
message_name = message.get_structure().get_name()
if message_name == 'prepare-window-handle': #Assign the window id to display in
imagesink = message.src
imagesink.set_window_handle(self.X_id)
return True
def on_error(self, msg):
print('on_error():', msg.parse_error())
def quit(self, event):
self.pipeline.set_state(Gst.State.NULL)
event.Skip()
app = Receptor()
app.MainLoop()