Fork me on GitHub
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
Data Structures | Macros | Typedefs | Enumerations | Functions | Variables
janus_streaming.c File Reference

Janus Streaming plugin. More...

#include "plugin.h"
#include <jansson.h>
#include <errno.h>
#include <sys/poll.h>
#include <sys/time.h>
#include "../debug.h"
#include "../apierror.h"
#include "../config.h"
#include "../mutex.h"
#include "../rtp.h"
#include "../rtpsrtp.h"
#include "../rtcp.h"
#include "../record.h"
#include "../utils.h"
#include "../ip-utils.h"
Include dependency graph for janus_streaming.c:

Data Structures

struct  janus_streaming_rtp_keyframe
 
struct  janus_streaming_rtp_source
 
struct  janus_streaming_file_source
 
struct  multiple_fds
 
struct  janus_streaming_codecs
 
struct  janus_streaming_mountpoint
 
struct  janus_streaming_message
 
struct  janus_streaming_session
 
struct  janus_streaming_rtp_relay_packet
 

Macros

#define JANUS_STREAMING_VERSION   8
 
#define JANUS_STREAMING_VERSION_STRING   "0.0.8"
 
#define JANUS_STREAMING_DESCRIPTION   "This is a streaming plugin for Janus, allowing WebRTC peers to watch/listen to pre-recorded files or media generated by gstreamer."
 
#define JANUS_STREAMING_NAME   "JANUS Streaming plugin"
 
#define JANUS_STREAMING_AUTHOR   "Meetecho s.r.l."
 
#define JANUS_STREAMING_PACKAGE   "janus.plugin.streaming"
 
#define JANUS_STREAMING_VP8   0
 
#define JANUS_STREAMING_H264   1
 
#define JANUS_STREAMING_VP9   2
 
#define JANUS_STREAMING_ERROR_NO_MESSAGE   450
 
#define JANUS_STREAMING_ERROR_INVALID_JSON   451
 
#define JANUS_STREAMING_ERROR_INVALID_REQUEST   452
 
#define JANUS_STREAMING_ERROR_MISSING_ELEMENT   453
 
#define JANUS_STREAMING_ERROR_INVALID_ELEMENT   454
 
#define JANUS_STREAMING_ERROR_NO_SUCH_MOUNTPOINT   455
 
#define JANUS_STREAMING_ERROR_CANT_CREATE   456
 
#define JANUS_STREAMING_ERROR_UNAUTHORIZED   457
 
#define JANUS_STREAMING_ERROR_CANT_SWITCH   458
 
#define JANUS_STREAMING_ERROR_CANT_RECORD   459
 
#define JANUS_STREAMING_ERROR_UNKNOWN_ERROR   470
 

Typedefs

typedef enum janus_streaming_type janus_streaming_type
 
typedef enum janus_streaming_source janus_streaming_source
 
typedef struct
janus_streaming_rtp_keyframe 
janus_streaming_rtp_keyframe
 
typedef struct
janus_streaming_rtp_source 
janus_streaming_rtp_source
 
typedef struct
janus_streaming_file_source 
janus_streaming_file_source
 
typedef struct multiple_fds multiple_fds
 
typedef struct
janus_streaming_codecs 
janus_streaming_codecs
 
typedef struct
janus_streaming_mountpoint 
janus_streaming_mountpoint
 
typedef struct
janus_streaming_message 
janus_streaming_message
 
typedef struct
janus_streaming_session 
janus_streaming_session
 
typedef struct
janus_streaming_rtp_relay_packet 
janus_streaming_rtp_relay_packet
 

Enumerations

enum  janus_streaming_type { janus_streaming_type_none = 0, janus_streaming_type_live, janus_streaming_type_on_demand }
 
enum  janus_streaming_source { janus_streaming_source_none = 0, janus_streaming_source_file, janus_streaming_source_rtp }
 

Functions

janus_plugincreate (void)
 
int janus_streaming_init (janus_callbacks *callback, const char *config_path)
 
void janus_streaming_destroy (void)
 
int janus_streaming_get_api_compatibility (void)
 
int janus_streaming_get_version (void)
 
const char * janus_streaming_get_version_string (void)
 
const char * janus_streaming_get_description (void)
 
const char * janus_streaming_get_name (void)
 
const char * janus_streaming_get_author (void)
 
const char * janus_streaming_get_package (void)
 
void janus_streaming_create_session (janus_plugin_session *handle, int *error)
 
struct janus_plugin_resultjanus_streaming_handle_message (janus_plugin_session *handle, char *transaction, json_t *message, json_t *jsep)
 
void janus_streaming_setup_media (janus_plugin_session *handle)
 
void janus_streaming_incoming_rtp (janus_plugin_session *handle, int video, char *buf, int len)
 
void janus_streaming_incoming_rtcp (janus_plugin_session *handle, int video, char *buf, int len)
 
void janus_streaming_hangup_media (janus_plugin_session *handle)
 
void janus_streaming_destroy_session (janus_plugin_session *handle, int *error)
 
json_tjanus_streaming_query_session (janus_plugin_session *handle)
 
janus_streaming_mountpointjanus_streaming_create_rtp_source (uint64_t id, char *name, char *desc, int srtpsuite, char *srtpcrypto, gboolean doaudio, char *amcast, const janus_network_address *aiface, uint16_t aport, uint8_t acodec, char *artpmap, char *afmtp, gboolean doaskew, gboolean dovideo, char *vmcast, const janus_network_address *viface, uint16_t vport, uint8_t vcodec, char *vrtpmap, char *vfmtp, gboolean bufferkf, gboolean simulcast, uint16_t vport2, uint16_t vport3, gboolean dovskew, int rtp_collision, gboolean dodata, const janus_network_address *diface, uint16_t dport, gboolean buffermsg)
 
janus_streaming_mountpointjanus_streaming_create_file_source (uint64_t id, char *name, char *desc, char *filename, gboolean live, gboolean doaudio, gboolean dovideo)
 
janus_streaming_mountpointjanus_streaming_create_rtsp_source (uint64_t id, char *name, char *desc, char *url, char *username, char *password, gboolean doaudio, char *artpmap, char *afmtp, gboolean dovideo, char *vrtpmap, char *vfmtp, const janus_network_address *iface, gboolean error_on_failure)
 

Variables

GHashTable * mountpoints
 
janus_mutex mountpoints_mutex
 

Detailed Description

Janus Streaming plugin.

Author
Lorenzo Miniero loren.nosp@m.zo@m.nosp@m.eetec.nosp@m.ho.c.nosp@m.om

This is a streaming plugin for Janus, allowing WebRTC peers to watch/listen to pre-recorded files or media generated by another tool. Specifically, the plugin currently supports three different type of streams:

  1. on-demand streaming of pre-recorded media files (different streaming context for each peer);
  2. live streaming of pre-recorded media files (shared streaming context for all peers attached to the stream);
  3. live streaming of media generated by another tool (shared streaming context for all peers attached to the stream).

For what concerns types 1. and 2., considering the proof of concept nature of the implementation the only pre-recorded media files that the plugins supports right now are raw mu-Law and a-Law files: support is of course planned for other additional widespread formats as well.

For what concerns type 3., instead, the plugin is configured to listen on a couple of ports for RTP: this means that the plugin is implemented to receive RTP on those ports and relay them to all peers attached to that stream. Any tool that can generate audio/video RTP streams and specify a destination is good for the purpose: the examples section contains samples that make use of GStreamer (http://gstreamer.freedesktop.org/) but other tools like FFmpeg (http://www.ffmpeg.org/), LibAV (http://libav.org/) or others are fine as well. This makes it really easy to capture and encode whatever you want using your favourite tool, and then have it transparently broadcasted via WebRTC using Janus. Notice that we recently added the possibility to also add a datachannel track to an RTP streaming mountpoint: this allows you to send, via UDP, a text-based message to relay via datachannels (e.g., the title of the current song, if this is a radio streaming channel). When using this feature, though, beware that you'll have to stay within the boundaries of the MTU, as each message will have to stay within the size of an UDP packet.

Streams to make available are listed in the plugin configuration file. A pre-filled configuration file is provided in conf/janus.plugin.streaming.cfg and includes a stream of every type.

To add more streams or modify the existing ones, you can use the following syntax:

[stream-name]
type = rtp|live|ondemand|rtsp
       rtp = stream originated by an external tool (e.g., gstreamer or
             ffmpeg) and sent to the plugin via RTP
       live = local file streamed live to multiple listeners
              (multiple listeners = same streaming context)
       ondemand = local file streamed on-demand to a single listener
                  (multiple listeners = different streaming contexts)
       rtsp = stream originated by an external RTSP feed (only
              available if libcurl support was compiled)
id = <unique numeric ID>
description = This is my awesome stream
is_private = yes|no (private streams don't appear when you do a 'list' request)
filename = path to the local file to stream (only for live/ondemand)
secret = <optional password needed for manipulating (e.g., destroying
                or enabling/disabling) the stream>
pin = <optional password needed for watching the stream>
audio = yes|no (do/don't stream audio)
video = yes|no (do/don't stream video)
   The following options are only valid for the 'rtp' type:
data = yes|no (do/don't stream text via datachannels)
audioport = local port for receiving audio frames
audiomcast = multicast group port for receiving audio frames, if any
audioiface = network interface or IP address to bind to, if any (binds to all otherwise)
audiopt = <audio RTP payload type> (e.g., 111)
audiortpmap = RTP map of the audio codec (e.g., opus/48000/2)
audiofmtp = Codec specific parameters, if any
audioskew = yes|no (whether the plugin should perform skew
        analisys and compensation on incoming audio RTP stream, EXPERIMENTAL)
videoport = local port for receiving video frames (only for rtp)
videomcast = multicast group port for receiving video frames, if any
videoiface = network interface or IP address to bind to, if any (binds to all otherwise)
videopt = <video RTP payload type> (e.g., 100)
videortpmap = RTP map of the video codec (e.g., VP8/90000)
videofmtp = Codec specific parameters, if any
videobufferkf = yes|no (whether the plugin should store the latest
        keyframe and send it immediately for new viewers, EXPERIMENTAL)
videosimulcast = yes|no (do|don't enable video simulcasting)
videoport2 = second local port for receiving video frames (only for rtp, and simulcasting)
videoport3 = third local port for receiving video frames (only for rtp, and simulcasting)
videoskew = yes|no (whether the plugin should perform skew
        analisys and compensation on incoming video RTP stream, EXPERIMENTAL)
collision = in case of collision (more than one SSRC hitting the same port), the plugin
        will discard incoming RTP packets with a new SSRC unless this many milliseconds
        passed, which would then change the current SSRC (0=disabled)
dataport = local port for receiving data messages to relay
dataiface = network interface or IP address to bind to, if any (binds to all otherwise)
databuffermsg = yes|no (whether the plugin should store the latest
        message and send it immediately for new viewers)

In case you want to use SRTP for your RTP-based mountpoint, you'll need
to configure the SRTP-related properties as well, namely the suite to
use for hashing (32 or 80) and the crypto information for decrypting
the stream (as a base64 encoded string the way SDES does it). Notice
that with SRTP involved you'll have to pay extra attention to what you
feed the mountpoint, as you may risk getting SRTP decrypt errors:
srtpsuite = 32
srtpcrypto = WbTBosdVUZqEb6Htqhn+m3z7wUh4RJVR8nE15GbN

The following options are only valid for the 'rstp' type:
url = RTSP stream URL
rtsp_user = RTSP authorization username, if needed
rtsp_pwd = RTSP authorization password, if needed
rtsp_failcheck = whether an error should be returned if connecting to the RTSP server fails (default=yes)
rtspiface = network interface IP address or device name to listen on when receiving RTSP streams

Streaming API

The Streaming API supports several requests, some of which are synchronous and some asynchronous. There are some situations, though, (invalid JSON, invalid request) which will always result in a synchronous error response even for asynchronous requests.

list , create , destroy , recording , edit , enable and disable are synchronous requests, which means you'll get a response directly within the context of the transaction. list lists all the available streams; create allows you to create a new mountpoint dynamically, as an alternative to using the configuration file; destroy removes a mountpoint and destroys it; recording instructs the plugin on whether or not a live RTP stream should be recorded while it's broadcasted; enable and disable respectively enable and disable a mountpoint, that is decide whether or not a mountpoint should be available to users without destroying it. edit allows you to dynamically edit some mountpoint properties (e.g., the PIN);

The watch , start , pause , switch and stop requests instead are all asynchronous, which means you'll get a notification about their success or failure in an event. watch asks the plugin to prepare the playout of one of the available streams; start starts the actual playout; pause allows you to pause a playout without tearing down the PeerConnection; switch allows you to switch to a different mountpoint of the same kind (note: only live RTP mountpoints supported as of now) without having to stop and watch the new one; stop stops the playout and tears the PeerConnection down.

Notice that, in general, all users can create mountpoints, no matter what type they are. If you want to limit this functionality, you can configure an admin admin_key in the plugin settings. When configured, only "create" requests that include the correct admin_key value in an "admin_key" property will succeed, and will be rejected otherwise.

Actual API docs: TBD.

Plugins

Macro Definition Documentation

#define JANUS_STREAMING_AUTHOR   "Meetecho s.r.l."
#define JANUS_STREAMING_DESCRIPTION   "This is a streaming plugin for Janus, allowing WebRTC peers to watch/listen to pre-recorded files or media generated by gstreamer."
#define JANUS_STREAMING_ERROR_CANT_CREATE   456
#define JANUS_STREAMING_ERROR_CANT_RECORD   459
#define JANUS_STREAMING_ERROR_CANT_SWITCH   458
#define JANUS_STREAMING_ERROR_INVALID_ELEMENT   454
#define JANUS_STREAMING_ERROR_INVALID_JSON   451
#define JANUS_STREAMING_ERROR_INVALID_REQUEST   452
#define JANUS_STREAMING_ERROR_MISSING_ELEMENT   453
#define JANUS_STREAMING_ERROR_NO_MESSAGE   450
#define JANUS_STREAMING_ERROR_NO_SUCH_MOUNTPOINT   455
#define JANUS_STREAMING_ERROR_UNAUTHORIZED   457
#define JANUS_STREAMING_ERROR_UNKNOWN_ERROR   470
#define JANUS_STREAMING_H264   1
#define JANUS_STREAMING_NAME   "JANUS Streaming plugin"
#define JANUS_STREAMING_PACKAGE   "janus.plugin.streaming"
#define JANUS_STREAMING_VERSION   8
#define JANUS_STREAMING_VERSION_STRING   "0.0.8"
#define JANUS_STREAMING_VP8   0
#define JANUS_STREAMING_VP9   2

Typedef Documentation

typedef struct multiple_fds multiple_fds

Enumeration Type Documentation

Enumerator
janus_streaming_source_none 
janus_streaming_source_file 
janus_streaming_source_rtp 
Enumerator
janus_streaming_type_none 
janus_streaming_type_live 
janus_streaming_type_on_demand 

Function Documentation

janus_plugin* create ( void  )
janus_streaming_mountpoint * janus_streaming_create_file_source ( uint64_t  id,
char *  name,
char *  desc,
char *  filename,
gboolean  live,
gboolean  doaudio,
gboolean  dovideo 
)
janus_streaming_mountpoint * janus_streaming_create_rtp_source ( uint64_t  id,
char *  name,
char *  desc,
int  srtpsuite,
char *  srtpcrypto,
gboolean  doaudio,
char *  amcast,
const janus_network_address aiface,
uint16_t  aport,
uint8_t  acodec,
char *  artpmap,
char *  afmtp,
gboolean  doaskew,
gboolean  dovideo,
char *  vmcast,
const janus_network_address viface,
uint16_t  vport,
uint8_t  vcodec,
char *  vrtpmap,
char *  vfmtp,
gboolean  bufferkf,
gboolean  simulcast,
uint16_t  vport2,
uint16_t  vport3,
gboolean  dovskew,
int  rtp_collision,
gboolean  dodata,
const janus_network_address diface,
uint16_t  dport,
gboolean  buffermsg 
)
janus_streaming_mountpoint * janus_streaming_create_rtsp_source ( uint64_t  id,
char *  name,
char *  desc,
char *  url,
char *  username,
char *  password,
gboolean  doaudio,
char *  artpmap,
char *  afmtp,
gboolean  dovideo,
char *  vrtpmap,
char *  vfmtp,
const janus_network_address iface,
gboolean  error_on_failure 
)
void janus_streaming_create_session ( janus_plugin_session handle,
int *  error 
)
void janus_streaming_destroy ( void  )
void janus_streaming_destroy_session ( janus_plugin_session handle,
int *  error 
)
int janus_streaming_get_api_compatibility ( void  )
const char * janus_streaming_get_author ( void  )
const char * janus_streaming_get_description ( void  )
const char * janus_streaming_get_name ( void  )
const char * janus_streaming_get_package ( void  )
int janus_streaming_get_version ( void  )
const char * janus_streaming_get_version_string ( void  )
struct janus_plugin_result * janus_streaming_handle_message ( janus_plugin_session handle,
char *  transaction,
json_t message,
json_t jsep 
)
void janus_streaming_hangup_media ( janus_plugin_session handle)
void janus_streaming_incoming_rtcp ( janus_plugin_session handle,
int  video,
char *  buf,
int  len 
)
void janus_streaming_incoming_rtp ( janus_plugin_session handle,
int  video,
char *  buf,
int  len 
)
int janus_streaming_init ( janus_callbacks callback,
const char *  config_path 
)
json_t * janus_streaming_query_session ( janus_plugin_session handle)
void janus_streaming_setup_media ( janus_plugin_session handle)

Variable Documentation

GHashTable* mountpoints
janus_mutex mountpoints_mutex