This is streamer used to stream anime on madoka.whs.in.th. It use videojs as the backend.
- A PHP capable server (no database is required)
- PHP
curl
module - nginx-push-stream-module
Streamer now comes with Dockerfile. To install with Docker,
docker run -p 80:80 -e FB_ID=<FBID> -e FB_SECRET=<FBSECRET> willwill/streaming
Replace <FBID>
and <FBSECRET>
by Facebook App ID and secret respectively (read the app setup section on how to register). You can add -v "<datafolder>:/var/www/html/data/:ro"
to mount a data folder (eg. video files) to serve at /data.
Note that this will assume that you're running behind reverse proxy. You can use without one, but it is a security risk. Make sure your reverse proxy can forward websocket.
In the same vhost that host the PHP pages, set
location /privpub/master {
push_stream_publisher;
push_stream_channels_path animestream_master;
push_stream_store_messages on;
}
location /privpub/chat {
push_stream_publisher;
push_stream_channels_path animestream_chat;
}
location /pub/online {
push_stream_publisher;
push_stream_channels_path animestream_online;
}
location ~ /sub/(.*) {
push_stream_subscriber;
push_stream_channels_path $1;
push_stream_message_template "{\"id\":~id~,\"channel\":\"~channel~\",\"text\":~text~}";
push_stream_ping_message_interval 10s;
}
location ~ /ev/(.*) {
push_stream_subscriber eventsource;
push_stream_channels_path $1;
push_stream_message_template "{\"id\":~id~,\"channel\":\"~channel~\",\"text\":~text~}";
push_stream_ping_message_interval 10s;
}
location ~ /lp/(.*) {
push_stream_subscriber long-polling;
push_stream_channels_path $1;
push_stream_message_template "{\"id\":~id~,\"channel\":\"~channel~\",\"text\":~text~}";
push_stream_longpolling_connection_ttl 30s;
}
location ~ /ws/(.*) {
push_stream_subscriber websocket;
push_stream_channels_path $1;
push_stream_message_template "{\"id\":~id~,\"channel\":\"~channel~\",\"text\":~text~}";
push_stream_ping_message_interval 10s;
}
- Register a Facebook app. Set app domain to link of your site.
- Edit config.php. Specify your given
FB_ID
andFB_SECRET
. - Test it out. Make sure the push server is running and accessible from the internet
- Go to
http://yoururl/path/to/streaming/?master=1
. If required, log in and retry the URL. - You'll see 4 buttons on top right, Open file, Open YouTube and Set Announce.
- Open file is to open video from arbitary URL. The video must be supported by client browsers' HTML5 video. MP4 usually works fine.
- Open YouTube is to open YouTube video. Known issue: you cannot switch from YouTube back to file. (videojs-youtube#347)
- Set Announce is to set chat's pinned message.
- No master authentication is performed. Do not attempt to use multiple masters.
- If the master lags everyone will loop. If a client lags, it will skip.
- If master pause the file player, clients will pause and attempt to seek to the same frame.
- If master seek the file player, clients will seek.
- Client can click at the lag meter below the chat bar to seek to the current keyframe time. (Needs to wait until next keyframe arrived)
Streamer use a very similar technique from Noke to keep client updated.
The master sends a "keyframe" every 3 seconds. The keyframe tells that what second in the video is now playing and also the file name and other state.
A client after connecting to the push server will wait for a keyframe which is if missing for 3 seconds will throw an error that master is missing. After receiving a keyframe, it loads the media and seeks to the specified time.
When the keyframe time and current video time of a client is over 3 seconds apart, the client corrects this by skipping to the keyframe time. (This also creates the loop effect as noted in the notes section, and also use to implement seeking)
In clients, there're "lag" and "ping" meters. Lag show how much that client's video time is apart from the server. Positive indicates lag behind. Ping show how long does keyframe stopped appearing at expected time. The ping meter starts counting 3 seconds after last keyframe arrived.
A keyframe may contains a "force" flag. Forced keyframes appear when server have manually changed media. Clients encoutering force flag will try to reload the media.
Licensed under StealItPl 1.1 or AGPLv3. You can use this only for non commercial use with under 100 active users in a month and retain this license term in your derivatives or you can use it under the terms of AGPLv3.
- Chatbox suggestion from @WolfKungz
- Nicochat inspiration from Nico Nico Douga
- Additional Nicochat testing from @zennnzonbolt @nonene_desu @WolfKungz
- OZView inspiration from Summer Wars
- Code portions from project menome and twitteroauth.php
- The keyframe approach is inspired from Synchtube.
- Anime streaming is inspired from /r/clannaddiscussion.