1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 import gst
19 import gobject
20
21
22
23
24
25
26
27
29 '''
30 I am a Python implementation of the GstFragment
31 '''
32 index = 0
33 name = 'fragment'
34 duration = 0
35 buf = None
36
37 __gproperties__ = {
38 'buffer': (gobject.TYPE_PYOBJECT,
39 'Buffer', 'GstBuffer with the data of the fragment',
40 gobject.PARAM_READABLE),
41 'index': (gobject.TYPE_UINT, 'Index', 'Index of the fragment',
42 0, gobject.G_MAXUINT, 0, gobject.PARAM_READABLE),
43 'name': (gobject.TYPE_STRING, 'Name', 'Name of the fragment',
44 'fragment', gobject.PARAM_READABLE),
45 'duration': (gobject.TYPE_UINT64, 'duration',
46 'Duration of the fragment in ns',
47 0, gst.CLOCK_TIME_NONE, 0, gobject.PARAM_READABLE)}
48
55
57 if prop.name == "name":
58 return self.name
59 if prop.name == "index":
60 return self.index
61 if prop.name == "duration":
62 return self.duration
63 if prop.name == "buffer":
64 return self.buf
65 else:
66 raise AttributeError('unknown property %s' % property.name)
67
68
70 '''
71 I am a python implementation the gstreamer hlssink element.
72 '''
73
74 __gstdetails__ = ('HLSSink', 'Sink',
75 'Sink for HTTP Live Streaming',
76 'Flumotion Dev Team')
77
78 __gsignals__ = {"new-fragment": (gobject.SIGNAL_RUN_LAST,
79 gobject.TYPE_NONE, []),
80 "eos": (gobject.SIGNAL_RUN_LAST,
81 gobject.TYPE_NONE, []),
82 "pull-fragment": (gobject.SIGNAL_RUN_LAST |
83 gobject.SIGNAL_ACTION,
84 gobject.TYPE_OBJECT, [])}
85
86 __gproperties__ = {
87 'fragment': (gobject.TYPE_OBJECT,
88 'fragment', 'last gstfragment',
89 gobject.PARAM_READABLE),
90 'sync': (gobject.TYPE_BOOLEAN,
91 'sync', 'sync', False,
92 gobject.PARAM_WRITABLE),
93 'playlist-max-window': (gobject.TYPE_INT,
94 'playlist max window', 'playlist max window',
95 0, gobject.G_MAXINT, 0, gobject.PARAM_WRITABLE),
96 'write-to-disk': (gobject.TYPE_BOOLEAN,
97 'Write to disk', 'Write to disk', False,
98 gobject.PARAM_WRITABLE)}
99
100 _sinkpadtemplate = gst.PadTemplate("sink",
101 gst.PAD_SINK,
102 gst.PAD_ALWAYS,
103 gst.caps_from_string("video/mpegts; "
104 "video/webm"))
105
107 gst.Element.__init__(self)
108
109 self._reset_fragment()
110 self._last_fragment = None
111 self._last_event_ts = gst.CLOCK_TIME_NONE
112
113 self.sinkpad = gst.Pad(self._sinkpadtemplate, "sink")
114 self.sinkpad.set_chain_function(self.chainfunc)
115 self.sinkpad.set_event_function(self.eventfunc)
116 self.add_pad(self.sinkpad)
117
119 if buf.flag_is_set(gst.BUFFER_FLAG_IN_CAPS):
120 self._in_caps = True
121 return gst.FLOW_OK
122
123 self._fragment.append(buf)
124 return gst.FLOW_OK
125
127 s = event.get_structure()
128 if event.type != gst.EVENT_CUSTOM_DOWNSTREAM or \
129 s.get_name() != 'GstForceKeyUnit':
130 return True
131
132
133 if len(self._fragment) == 0:
134 return True
135
136 self._finish_fragment(s['timestamp'], s['count'])
137 return True
138
140 if prop.name == "fragment":
141 return self._last_fragment
142
147
149 self._fragment = []
150 self._in_caps = False
151 self._last_event_ts = last_event_ts
152
180
181
185