Restreamer Plugin

The Restreamer plugin encapsulates those plugins which provide re-streaming from disparate ingest sources which are not natively handled via Red5 server; for example, not one of RTMP, RTSP (mobile), or WebRTC. Plugin configuration options are located in the conf/restreamer-plugin.properties configuration file; which includes the ability to enable or disable the IPCam or TS-ingest plugins. Legacy support for previous servlet implementations was retained where possible and is listed below in the appropriate sections.

API Servlet

Requests are made via POST with content-type application/json as a Provision in JSON format; Responses are returned in JSON format. The GET method is not supported an will return an HTTP error status.

   <servlet>
      <servlet-name>RestreamerServlet</servlet-name>
      <servlet-class>com.red5pro.restreamer.servlet.RestreamerServlet</servlet-class>
   </servlet>
   <servlet-mapping>
      <servlet-name>RestreamerServlet</servlet-name>
      <url-pattern>/restream</url-pattern>
   </servlet-mapping>

The servlet is commented-out in the live webapp web.xml

A note about provisions: there are required fields that must be specified per the implementation beyond what the Restreamer uses and they are:

  • guid - unique identifier
  • context - the context path
  • name - stream name
  • level - priority level (lower the number, the higher the priority 0 > 1)

The restreamer makes primary use of the parameters field in the provision which is a free-form key/value collection. The common keys used by both the IPCam (RTSP) and MPEG-TS plugins are as follows:

  • type - type of plugin, either ipcam or mpegts
  • action - action to perform, one of create, kill, or list with list being the default
  • port - the port being used for ingest

API Examples

IP Camera List

List IP Camera / RTSP ingests:

{
    "guid": "live/camera1",
    "context": "live",
    "name": "camera1",
    "level": 0,
    "parameters": {
        "type": "ipcam"
    }
}

action isn't enforced for list since its the default action.

IP Camera Create

Create a stream named camera1out from a connection to an IP Camera at 192.168.1.10:5443 Request:

{
    "guid": "live/camera1",
    "context": "live",
    "name": "camera1",
    "level": 0,
    "parameters": {
        "type": "ipcam",
        "action": "create",
        "scopename": "live",
        "outputname": "camera1out",
        "host": "192.168.1.10",
        "port": 5443
    }
}

Timeout response:

{
    "message": "Stream create timed out"
}

IP Camera Kill

Request:

{
    "guid": "live/camera1",
    "context": "live",
    "name": "camera1",
    "level": 0,
    "parameters": {
        "type": "ipcam",
        "action": "kill"
    }
}

Success:

{
    "message": "Stream killed"
}

MPEG-TS List

List MPEG-TS ingests

Request:

{
    "guid": "live/stream1",
    "context": "live",
    "name": "stream1",
    "level": 0,
    "parameters": {
        "type": "mpegts"
    }
}

action isn't enforced for list since its the default action.

Response:

{
    "message": "Endpoints",
    "endpoints": {}
}

MPEG-TS Create

MPEG-TS end-point creation

Request:

{
    "guid": "live/stream1",
    "context": "live",
    "name": "stream1",
    "level": 0,
    "parameters": {
        "type": "mpegts",
        "action": "create",
        "cast": "multicast",
        "ip": "239.5.5.5",
        "port": 5555
    }
}

Response:

{
    "message": "Stream created",
    "path": "/live/stream1"
}

MPEG-TS Kill

Kill only needs the stream name and the required Provision entries.

Request:

{
    "guid": "live/stream1",
    "context": "live",
    "name": "stream1",
    "level": 0,
    "parameters": {
        "type": "mpegts",
        "action": "kill"
    }
}

Success:

{
    "message": "Stream killed"
}

Failure:

{
    "message": "Stream kill failed"
}

IPCam Plugin

This plugin provides a means to ingest RTSP (IP Camera) camera sources.

IPCam Legacy Servlet

The FeedController servlet is an html entry point for web controller in the web.xml file. Typically it is a bean wired with auth and error handlers from red5-web.xml and set to the IPCam static instance. IPCam is a red5 plugin and functionality should be absorbed by the main pro-plugin class.

    <servlet>
        <servlet-name>FeedController</servlet-name>
        <servlet-class>com.red5pro.restreamer.ipcam.feeds.model.FeedController</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>FeedController</servlet-name>
        <url-pattern>/feed</url-pattern>
    </servlet-mapping>

MPEG-TS Ingest Plugin

This plugin provides a means to ingest MPEG-TS stream data over multicast and unicast UDP. Plugin configurations options are located in the conf/ts-ingest-plugin.properties configuration file.

Configuration

To create additional ingest listeners / streams, one may use the API servlet or the tsingest example webapp. Be aware that streams are subject to the same caveats as other Red5 Pro streams in that when they are detected as idle, they are shutdown. The idle timeout value is configured via the socket.idle.timeout parameter in milliseconds. In addition, the plugin subsystem will generate stream names if they are not supplied, the name is generated in this form: udp://239.5.5.5:5555 yields m2395555p5555. The prefixes are m = multicast and u = unicast, lastly a delimiter p for port.

A default scope is configured using the scope.name parameter, the live application scope is the default.

Recording to validate the stream, if live RTMP isn't working, can be accomplished by setting the broadcaststream.auto.record property to true in conf/red5.properties.

MPEG-TS Ingest Legacy Servlet

Access to add, kill, and list streams is provided via MPEGTSIngestServlet servlet. The servlet provides create, delete, and list access for MPEG-TS ingest streams. Responses are in JSON format. Any web application needing to manipulate MPEG-TS ingest streams will need the servlet descriptor shown below added to its web.xml file. Only the GET http method is supported.

    <servlet>
        <servlet-name>MPEGTSIngestServlet</servlet-name>
        <servlet-class>com.red5pro.mpegts.servlet.MPEGTSIngestServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>MPEGTSIngestServlet</servlet-name>
        <url-pattern>/mpegts</url-pattern>
    </servlet-mapping>

API Methods

  • Add / create - Creates a new TS ingest endpoint and associated ProStream
    • Required parameters: action, contextpath, streamname, cast, ip, port
    • URL: https://red5pro.com/tsingest/mpegts?action=create&contextpath=live&streamname=mystream&cast=[multicast|unicast]&ip=239.1.1.1&port=1234
  • Kill a stream - Stops and removes a TS ingest endpoint
    • Required parameters: action, streamname
    • URL: https://red5pro.com/tsingest/mpegts?action=kill&streamname=mystream
  • List - Lists current TS ingest endpoints
    • Required parameter: action
    • URL: https://red5pro.com/tsingest/mpegts?action=list

Method Examples

Added stream:

{"message":"Stream created","path":"live/room1/mystream"}

Endpoint listing:

{"message":"Endpoints","endpoints":{"m239111p1234":{"id":"m239111p1234","ip":"239.1.1.1","port":1234,"cast":"multicast","contextpath":"live","streamname":"mystream","audio":false,"video":true,"closed":false}}}

Killed stream:

{"message":"Stream killed"}

Web Application

An example web application tsingest may be found at Red5 Pro Examples and used as a guide for custom implementations.

Test source with FFMPEG

The basic format of an ffmpeg command is: ffmpeg [input arguments] -i [input url] [output arguments] [output url]

The input will be up to you based on whatever video sources you have available. For the output, all you need to do is make sure you're telling ffmpeg to output as MPEG-TS over UDP multicast or unicast.

Windows

An example command looks like this:

ffmpeg -f dshow -i video="My Webcam" -f mpegts udp://239.5.5.5:5555?pkt_size=188

To determine the available a/v devices on windows, use this command:

ffmpeg -list_devices true -f dshow -i dummy

On an ASUS laptop this command worked best:

ffmpeg -f dshow -rtbufsize 16M -i video="ASUS USB2.0 Webcam":audio="Microphone (Realtek High Definition Audio)" -video_size 640x480 -r 25 -threads 4 -c:v libx264 -pix_fmt yuv420p -bsf:v h264_mp4toannexb -profile:v baseline -level:v 3.2 -c:a aac -b:a 128k -ar 44100 -f mpegts "udp://239.5.5.5:5555"

Lenovo with external MS LifeCam example using alternate video source name:

./bin/ffmpeg -f dshow -rtbufsize 16M -video_size 352x288 -i video="@device_pnp_\\?\usb#vid_045e&pid_075d&mi_00#7&efedfc8&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global":audio="Microphone (Lenovo USB Audio)" -s 352x288 -r 25 -c:v libx264 -pix_fmt yuv420p -bsf:v h264_mp4toannexb -profile:v baseline -level:v 3.2 -preset ultrafast -tune zerolatency -b:v 420k -c:a aac -b:a 64k -ar 44100 -f mpegts "udp://239.5.5.5:5555"

The above output shows video bitrate forced to 420k, camera source capture matching the codec sizing, and codec presets

MacOS

Publish audio (aac 44100 stereo) and video (h264 profile baseline 3.2) over multicast:

ffmpeg -f avfoundation -video_size 640x480 -framerate 25 -i “0:0” -bsf:v h264_mp4toannexb -c:v libx264 -pix_fmt yuv420p -profile:v baseline -level:v 3.2 -c:a aac -b:a 128k -ar 44100 -f mpegts “udp://239.1.1.1:1234?pkt_size=188"

Linux

Publish a video-only stream over multicast:

ffmpeg -f video4linux2 -framerate 24 -i /dev/video0 -bsf:v h264_mp4toannexb -c:v libx264 -x264-params keyint=120:scenecut=0 -f mpegts udp://239.5.5.5:5555

Publish audio (aac 44100 stereo) and video (h264 profile baseline 3.2) over multicast:

ffmpeg -f pulse -i default -f video4linux2 -thread_queue_size 64 -framerate 25 -video_size 640x480 -i /dev/video0 -pix_fmt yuv420p -bsf:v h264_mp4toannexb -profile:v baseline -level:v 3.2 -c:v libx264 -x264-params keyint=120:scenecut=0 -c:a aac -b:a 128k -ar 44100 -f mpegts udp://239.5.5.5:5555

video size and thread queue size are adjusted to allow better streaming with live in ffmpeg

Verifying the stream by subscribing to it: ffplay -i udp://239.5.5.5:5555

File source

Publishing a stream over multicast from a media source file:

ffmpeg -re -stream_loop -1 -i [media file] -c:v h264 -bsf:v h264_mp4toannexb -profile:v baseline -c:a aac -b:a 128k -ar 44100 -f mpegts udp://239.5.5.5:5555?pkt_size=188

Unicast Testing with File Source

Test box has two NIC's installed on a 10.0.0.x network, with the primary server binding on 10.0.0.5.

First test is on the primary interface 10.0.0.5, first step creating the TS endpoint for consuming / listening:

http://localhost:5080/tsingest/mpegts?action=create&contextpath=live&streamname=mystream2&cast=unicast&ip=10.0.0.5&port=5678

Upon success message in the browser, start streaming with ffmpeg:

ffmpeg -re -stream_loop -1 -i sample.ts -c:v copy -c:a copy -f mpegts udp://10.0.0.5:5678?pkt_size=188

Second test is on the secondary interface 10.0.0.19, first step creating the TS endpoint for consuming / listening:

http://localhost:5080/tsingest/mpegts?action=create&contextpath=live&streamname=mystream1&cast=unicast&ip=10.0.0.19&port=1234

Upon success message in the browser, start streaming with ffmpeg:

ffmpeg -re -stream_loop -1 -i sample.ts -c:v copy -c:a copy -f mpegts udp://10.0.0.19:1234?pkt_size=188

Lastly is the binding on the any address 0.0.0.0:

http://localhost:5080/tsingest/mpegts?action=create&contextpath=live&streamname=any&cast=unicast&ip=0.0.0.0&port=1111

Upon success message in the browser, start streaming with ffmpeg on a local IP to the box paying close attention that the ports match:

ffmpeg -re -stream_loop -1 -i sample.ts -c:v copy -c:a copy -f mpegts udp://10.0.0.5:1111?pkt_size=188

References