~jamalta/+junk/rtmpy

« back to all changes in this revision

Viewing changes to rtmp/interfaces.py

  • Committer: Jamal Fanaian
  • Date: 2010-01-26 20:09:26 UTC
  • Revision ID: jamal.fanaian@gmail.com-20100126200926-cthyamobyb5t7bfz
PulledĀ fromĀ git

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (c) 2007-2009 The RTMPy Project.
 
2
# See LICENSE for details.
 
3
 
 
4
"""
 
5
Interface documentation for RTMP primitives.
 
6
 
 
7
@since: 0.1
 
8
"""
 
9
 
 
10
from zope.interface import Interface, Attribute
 
11
 
 
12
 
 
13
class IHeader(Interface):
 
14
    """
 
15
    An RTMP Header.
 
16
    """
 
17
 
 
18
    channelId = Attribute("An C{int} representing the linked channel.")
 
19
    relative = Attribute(
 
20
        "A C{bool} which is C{True} if this header is relative to the "
 
21
        "previous. If C{False} then the header completely replaces the "
 
22
        "previous. If this value is C{False} then all other attributes on "
 
23
        "the header are guaranteed to be populated.")
 
24
    timestamp = Attribute(
 
25
        "An C{int} time value - not sure what this represents atm.")
 
26
    datatype = Attribute(
 
27
        "The datatype for the corresponding channel. See "
 
28
        "U{RTMP datatypes on OSFlash<http://osflash.org/documentation/rtmp#rtmp_datatypes>} "
 
29
        "for a list of possibles.")
 
30
    bodyLength = Attribute(
 
31
        "An C{int} which represents the length of the channel body.")
 
32
    streamId = Attribute(
 
33
        "An C{int} representing the linked stream.")
 
34
 
 
35
 
 
36
class IChannel(Interface):
 
37
    """
 
38
    An RTMP channel. A channel acts as an intermediary between two endpoints, 
 
39
    as well as providing context information for protocol en/decoding.
 
40
    """
 
41
 
 
42
    bytes = Attribute(
 
43
        "The total number of bytes that have been routed through this "
 
44
        "channel.")
 
45
    frames = Attribute(
 
46
        "The total number of frames that have been routed through this "
 
47
        "channel.")
 
48
    bodyRemaining = Attribute(
 
49
        "The number of bytes that remain until this channel's body is "
 
50
        "considered complete.")
 
51
    observer = Attribute(
 
52
        "An L{IChannelObserver} object that listens for events on this "
 
53
        "channel.")
 
54
 
 
55
    def registerManager(manager):
 
56
        """
 
57
        Registers a channel manager.
 
58
 
 
59
        @param manager: L{IChannelManager}
 
60
        @raise TypeError: If manager does not provide L{IChannelManager}
 
61
        """
 
62
 
 
63
    def registerObserver(observer):
 
64
        """
 
65
        Registers an observer for this channel. If the channel is buffering
 
66
        data then the observer must be notified immediately.
 
67
 
 
68
        @param observer: L{IChannelObserver}
 
69
        @raise TypeError: If observer does not provide L{IChannelObserver}
 
70
        """
 
71
 
 
72
    def getHeader():
 
73
        """
 
74
        Returns the header for this channel. Returns C{None} if no header was
 
75
        applied to this channel.
 
76
 
 
77
        @rtype: L{IHeader} or C{None}.
 
78
        """
 
79
 
 
80
    def setHeader(header):
 
81
        """
 
82
        Sets the header for this channel. If the header is relative, then it
 
83
        is 'merged' with the last absolute header. If no header has been
 
84
        applied to this channel then L{IChannelManager.initialiseChannel} must
 
85
        be called.
 
86
 
 
87
        @param header: The header to apply to this channel.
 
88
        @type header: L{IHeader}
 
89
        @raise TypeError: If C{header} does not provide L{IHeader}
 
90
        """
 
91
 
 
92
    def dataReceived(data):
 
93
        """
 
94
        Called when data has been received for this channel. The channel must
 
95
        buffer the data until an observer has been registered.
 
96
 
 
97
        @type data: C{str}
 
98
        """
 
99
 
 
100
    def reset():
 
101
        """
 
102
        Called to reset the context information. Called when after a channel
 
103
        completes its body. This function should reset all contextual values
 
104
        except the header.
 
105
        """
 
106
 
 
107
 
 
108
class IChannelManager(Interface):
 
109
    """
 
110
    The channel manager handles the interactions between its registered
 
111
    channels and the outside world.
 
112
    """
 
113
 
 
114
    frameSize = Attribute(
 
115
        "A read-only C{int} that defines the size (in bytes) of each frame "
 
116
        "body. Set the frameSize via L{setFrameSize}")
 
117
 
 
118
    def getChannel(channelId):
 
119
        """
 
120
        Returns a L{IChannel} object based on the channeId.
 
121
 
 
122
        @raise IndexError: C{channelId} is not in range.
 
123
        @rtype: L{IChannel}
 
124
        """
 
125
 
 
126
    def getNextAvailableChannelId():
 
127
        """
 
128
        Returns the next available channel id.
 
129
 
 
130
        @rtype: C{int}
 
131
        @raise OverflowError: There are no free channels.
 
132
        """
 
133
 
 
134
    def channelComplete(channel):
 
135
        """
 
136
        Called when enough data has been written to the channel to satisfy
 
137
        the body. The manager's job is to act appropriately on the event.
 
138
        """
 
139
 
 
140
    def initialiseChannel(channel):
 
141
        """
 
142
        Called when a channel needs to be initialised to begin accepting data.
 
143
        This method must call L{IChannel.reset}.
 
144
 
 
145
        @param channel: The channel to initialise.
 
146
        @type channel: L{IChannel}
 
147
        """
 
148
 
 
149
    def setFrameSize(size):
 
150
        """
 
151
        Called to set the frame size, informing all registered channels of the
 
152
        update.
 
153
 
 
154
        @param size: The new frame size.
 
155
        @type size: C{int}
 
156
        """
 
157
 
 
158
 
 
159
class IChannelObserver(Interface):
 
160
    """
 
161
    Observes L{IChannel} events.
 
162
    """
 
163
 
 
164
    def dataReceived(data):
 
165
        """
 
166
        Called when the channel receives some data.
 
167
 
 
168
        @param data: The data received by the channel.
 
169
        @type data: C{str}
 
170
        """
 
171
 
 
172
    def bodyComplete():
 
173
        """
 
174
        Called when the amount of data received by the channel matches that
 
175
        of its header.
 
176
        """
 
177
 
 
178
    def headerChanged(header):
 
179
        """
 
180
        A new header was set on the channel.
 
181
 
 
182
        @param header: The new relative header.
 
183
        @type header: L{IHeader}
 
184
        """
 
185
 
 
186
 
 
187
class IChannelScheduler(Interface):
 
188
    """
 
189
    A channel scheduler is meant to iteratively supply 'active' channels via
 
190
    the L{getNextChannel} method. Used for RTMP encoding.
 
191
    """
 
192
 
 
193
    def activateChannel(channel):
 
194
        """
 
195
        Activates a channel for scheduling.
 
196
 
 
197
        @param channel: The channel to activate.
 
198
        @type channel: L{IChannel}
 
199
        """
 
200
 
 
201
    def deactivateChannel(channel):
 
202
        """
 
203
        Deactivates a channel for scheduling.
 
204
 
 
205
        @param channel: The channel to deactivate.
 
206
        @type channel: L{IChannel}
 
207
        """
 
208
 
 
209
    def getNextChannel():
 
210
        """
 
211
        Returns the next active channel. The definition of 'next' is up to the
 
212
        implementing class. If there are no more active channels then C{None}
 
213
        should be returned.
 
214
        """
 
215
 
 
216
 
 
217
class ICodec(Interface):
 
218
    """
 
219
    """
 
220
 
 
221
    deferred = Attribute("")
 
222
 
 
223
    def getJob(self):
 
224
        """
 
225
        """
 
226
 
 
227
    def start(when):
 
228
        """
 
229
        """
 
230
 
 
231
    def pause():
 
232
        """
 
233
        """
 
234
 
 
235
    def registerObserver(observer):
 
236
        """
 
237
 
 
238
        @type observer: L{ICodecObserver}
 
239
        """
 
240
 
 
241
 
 
242
class ICodecObserver(Interface):
 
243
    """
 
244
    Observes RTMP codec events.
 
245
    """
 
246
 
 
247
    def started():
 
248
        """
 
249
        Called when the codec has re/started.
 
250
        """
 
251
 
 
252
    def stopped():
 
253
        """
 
254
        Called when encoding has paused.
 
255
        """
 
256
 
 
257
 
 
258
class IHandshakeObserver(Interface):
 
259
    """
 
260
    Observes handshake events.
 
261
    """
 
262
 
 
263
    def handshakeSuccess():
 
264
        """
 
265
        Handshaking was successful.
 
266
        """
 
267
 
 
268
    def handshakeFailure(reason):
 
269
        """
 
270
        Handshaking failed.
 
271
 
 
272
        @param reason: Why the handshake failed.
 
273
        @type reason: Exception wrapped L{Failure}
 
274
        """
 
275
 
 
276
    def write(data):
 
277
        """
 
278
        Called when the handshake negotiator writes some data.
 
279
        """
 
280
 
 
281
 
 
282
class IHandshakeNegotiator(Interface):
 
283
    """
 
284
    Negotiates handshakes.
 
285
    """
 
286
 
 
287
    observer = Attribute(
 
288
        "An L{IHandshakeObserver} that listens for events from this "
 
289
        "negotiator")
 
290
    server = Attribute(
 
291
        "The server handshake token. Can be L{ServerToken} or C{None}")
 
292
    client = Attribute(
 
293
        "The client handshake token. Can be L{ServerToken} or C{None}")
 
294
 
 
295
    def start(uptime=None, version=None):
 
296
        """
 
297
        Called to start the handshaking process. You can supply the uptime and
 
298
        version, otherwise they will be worked out automatically. The version
 
299
        specifically will be set to enable H.264 streaming.
 
300
        """
 
301
 
 
302
    def dataReceived(self, data):
 
303
        """
 
304
        Called when handshaking data has been received.
 
305
        """
 
306
 
 
307
 
 
308
class IEvent(Interface):
 
309
    """
 
310
    An RTMP Event.
 
311
 
 
312
    @see: U{RTMP datatypes on OSFlash (external)
 
313
        <http://osflash.org/documentation/rtmp#rtmp_datatypes>}
 
314
    """
 
315
 
 
316
    def encode(bbs):
 
317
        """
 
318
        Encodes the event instance to C{bbs}. Can return a L{defer.Deferred}.
 
319
 
 
320
        @param bbs: A stream object to write to.
 
321
        @type bbs: L{rtmpy.util.BufferedByteStream}
 
322
        """
 
323
 
 
324
    def decode(bbs):
 
325
        """
 
326
        Decodes the event instance from C{bbs}. Can return a L{defer.Deferred}.
 
327
 
 
328
        @param bbs: A stream object to read from.
 
329
        @type bbs: L{rtmpy.util.BufferedByteStream}
 
330
        """
 
331
 
 
332
    def dispatch(listener):
 
333
        """
 
334
        Dispatch the event to the listener. Calls the correct method with the
 
335
        correct args according to L{IEventListener}.
 
336
 
 
337
        @param listener: Receives the event dispatch request.
 
338
        @type listener: L{IEventListener}
 
339
        @return: Whatever is returned by the call to C{listener}.
 
340
        @rtype: C{mixed}
 
341
        """
 
342
 
 
343
 
 
344
class IEventListener(Interface):
 
345
    """
 
346
    Receives dispatched events.
 
347
    """
 
348
 
 
349
    def onInvoke(invoke):
 
350
        """
 
351
        Called when an invoke event have been received.
 
352
 
 
353
        @param invoke: The object representing the call request. See
 
354
            L{rtmpy.rtmp.event.Invoke} for an example implementation.
 
355
        @return: The response, or a L{defer.Deferred} that will return the
 
356
            response.
 
357
        """
 
358
 
 
359
    def onNotify(notify):
 
360
        """
 
361
        Similar to L{onInvoke} but no response is expected and will be
 
362
        ignored.
 
363
 
 
364
        @param notify: The object representing the notify request.
 
365
        @return: Ignored
 
366
        """
 
367
 
 
368
    def onFrameSize(size):
 
369
        """
 
370
        Called when the RTMP frame size has changed.
 
371
 
 
372
        @param size: The new size of the frames.
 
373
        @type size: C{int}
 
374
        """
 
375
 
 
376
    def onBytesRead(bytes):
 
377
        """
 
378
        Called when the connected endpoint reports the number of raw bytes
 
379
        read from the stream.
 
380
 
 
381
        @param bytes: The number of bytes read.
 
382
        @type bytes: C{int}
 
383
        """
 
384
 
 
385
    def onControlMessage(message):
 
386
        """
 
387
        Called when a control message is received by the connected endpoint.
 
388
 
 
389
        @param message: The received message.
 
390
        @type message: L{rtmpy.rtmp.event.ControlMessage}
 
391
        """
 
392
 
 
393
    def onDownstreamBandwidth(bandwidth):
 
394
        """
 
395
        Called when the connected endpoint reports its downstream bandwidth
 
396
        limit.
 
397
 
 
398
        @param bandwidth: The amount of bandwidth available (it appears to be
 
399
            measured in KBps).
 
400
        @type bandwidth: C{int}
 
401
        """
 
402
 
 
403
    def onUpstreamBandwidth(bandwidth, extra):
 
404
        """
 
405
        Called when the connected endpoint reports its upstream bandwidth
 
406
        limit.
 
407
 
 
408
        @param bandwidth: The amount of bandwidth available (it appears to be
 
409
            measured in KBps).
 
410
        @type bandwidth: C{int}
 
411
        @param extra: Not quite sure what this represents atm.
 
412
        @type extra: C{int}
 
413
        """
 
414
 
 
415
    def onAudioData(data):
 
416
        """
 
417
        Called when audio data is received.
 
418
 
 
419
        @param data: The raw data received on the audio channel.
 
420
        @type data: C{str}
 
421
        """
 
422
 
 
423
    def onVideoData(data):
 
424
        """
 
425
        Called when video data is received.
 
426
 
 
427
        @param data: The raw data received on the video channel.
 
428
        @type data: C{str}
 
429
        """
 
430
 
 
431
 
 
432
class IConsumingStream(Interface):
 
433
    """
 
434
    Deals with part of a stream that linked with decoding RTMP events.
 
435
    """
 
436
 
 
437
    def channelRegistered(channel):
 
438
        """
 
439
        Called when a channel has registered itself to this stream.
 
440
 
 
441
        @type channel: L{IChannel}
 
442
        """
 
443
 
 
444
    def channelUnregistered(channel):
 
445
        """
 
446
        Called when a channel has unregistered itself from this channel
 
447
 
 
448
        @type channel: L{IChannel}
 
449
        """
 
450
 
 
451
    def dispatchEvent(event, channel):
 
452
        """
 
453
        Called to dispatch an event to the stream.
 
454
 
 
455
        @type event: L{IEvent}
 
456
        @param channel: The channel that the event was generated from.
 
457
        @type channel: L{IChannel}
 
458
        """
 
459
 
 
460
 
 
461
class IProducingStream(Interface):
 
462
    """
 
463
    Deals with part of a stream that linked with encoding RTMP events.
 
464
    """
 
465
 
 
466
    def registerChannel(channel):
 
467
        """
 
468
        Called to register a channel to this stream.
 
469
 
 
470
        @type channel: L{IChannel}
 
471
        """
 
472
 
 
473
    def unregisterChannel(channel):
 
474
        """
 
475
        Called to unregister a channel from this stream.
 
476
 
 
477
        @type channel: L{IChannel}
 
478
        """
 
479
 
 
480
    def writeEvent(event, channel=None):
 
481
        """
 
482
        Write an event to the stream. If channel is C{None} then one will be
 
483
        allocated.
 
484
 
 
485
        @type event: L{IEvent}
 
486
        @param channel: The channel that the event was generated from.
 
487
        @type channel: L{IChannel}
 
488
        """
 
489
 
 
490
 
 
491
class IStreamable(Interface):
 
492
    """
 
493
    Flags the implementing class as streaming. Used for marking audio/video
 
494
    data events so that any observers are immediately notified.
 
495
    """
 
496
 
 
497
 
 
498
class IStreamManager(Interface):
 
499
    """
 
500
    A manager that handles RTMP streams.
 
501
    """
 
502
 
 
503
    def registerStream(streamId, stream):
 
504
        """
 
505
        Registers a L{IStream} instance to the manager, based on the C{streamId}.
 
506
 
 
507
        @param streamId: The id used to identify the stream to the manager.
 
508
        @type streamId: C{int}
 
509
        @param stream: The stream instance.
 
510
        @type stream: L{interfaces.IStream}
 
511
        @raise ValueError: C{streamId} is not in the correct range.
 
512
        @raise TypeError: C{stream} does not implement L{interfaces.IStream}.
 
513
        @raise IndexError: C{streamId} is already registered to another stream.
 
514
        """
 
515
 
 
516
    def removeStream(streamId):
 
517
        """
 
518
        Removes the stream from this manager.
 
519
 
 
520
        @param streamId: The id used to identify the stream to the manager.
 
521
        @type streamId: C{int}
 
522
        @return: The stream object that has been removed.
 
523
        @rtype: L{IStream}
 
524
        @raise ValueError: C{streamId} is not in the correct range.
 
525
        @raise IndexError: C{streamId} does not have a stream registered to it.
 
526
        """
 
527
 
 
528
    def getStream(streamId):
 
529
        """
 
530
        """