@Deprecated This project is no longer maintained, An equivilant one is available, look into streamy/
This is a minimalistic video sharing platform. Capable of sharing videos (video on-demand) and live streaming to mass audience if scaled well by the way.
It has pretty basic features like users, channels, commenting, searching, uploading videos and processing them, creating playlists, going on a one way live and that's pretty much it.
You should have a MongoDB and Redis instance ready to plug in. Also, nginx is required for this project to work properly. But don't install it yet, it should be compiled manually; we'll get to that later.
Install FFMPEG version 4.3.1 or higher You don't have to compile it, on Ubuntu at least in already comes with aac and x264 encoder by default so just install it in whatever way you like.
Later on you are required to provide path of executables of ffmpeg to the env file. use these command to get the paths:
which ffmpeg
which ffprobe
which ffplay
Pretty much all the env files are required.
Rename config.env.example
to config.env
There are explanations for each env variable, so check the file out.
Compile the nginx with nginx-rtmp-module
this module is required to get live streaming working.
You can use any guide you want, but this Alibaba guide is a pretty simple to follow.
Do this, and restart the nginx process.
Don't forget to provide path for video files generated by nginx-rtmp-module and video-on-demand generated by nodejs itself in the config file. nginx will serve them. There are comments for them to guide you, check them out.
Don't forget to provide ssl keys and dhparam paths in nginx.
Open these ports, nginx will use 80 and 443 to serve content. And it will user 1935 for rtmp.
The default nginx user used in nginx.conf is www-data, if you want, change it to whatever username you want. but you got to watch out to give permission of directories used by nginx to the user running nginx (including ffmpeg log directory).
npm install
npm start
This project is capable of video sharing (video on-demand). Newly uploaded videos have to be transcoded to HLS packaging. In this process the video and subtitles uploaded by users will be packaged to HLS packaging using FFMPEG. This will produce output of multiple versions of the same video, like different codecs, resolutions, bitrates and etc. Live streaming is handled by Nginx and a module called nginx-rtmp-module, but it is controlled and secured by this project. One user can have many channels, and one channel can have many videos and lives. But only users can comment not channels. There is oAuth2.0 functionality and 2FA functionality for your emails.
There are two commands of FFMPEG used in this project to achive hls packaging. The first one is a command that runs first and takes the video as input and outputs 3 variants of the video with associated m3u8 files and one final master m3u8. Each variant is in different quality and resolution to give the player of user adaptive bitrate streaming.
ffmpeg -loglevel error -y -i ../input.mp4 \
-filter_complex \
"[0:v]fps=fps=30,split=3[v1][v2][v3]; \
[v1]scale=width=-2:height=1080[1080p]; [v2]scale=width=-2:height=720[720p]; [v3]scale=width=-2:height=360[360p]" \
-codec:v libx264 -crf:v 23 -profile:v high -pix_fmt:v yuv420p -rc-lookahead:v 60 -force_key_frames:v expr:'gte(t,n_forced*2.000)' -preset:v "medium" -b-pyramid:v "strict" \
-map [1080p] -maxrate:v:0 2000000 -bufsize:v:0 2*2000000 -level:v:0 4.0 \
-map [720p] -maxrate:v:1 1200000 -bufsize:v:1 2*1000000 -level:v:1 3.1 \
-map [360p] -maxrate:v:2 700000 -bufsize:v:2 2*500000 -level:v:2 3.1 \
-codec:a aac -ac:a 2 \
-map 0:a:0 -b:a:0 192000 \
-map 0:a:0 -b:a:1 128000 \
-map 0:a:0 -b:a:2 96000 \
-f hls \
-hls_flags +independent_segments+program_date_time+single_file \
-hls_time 6 \
-hls_playlist_type vod \
-hls_segment_type mpegts \
-master_pl_name 'master.m3u8' \
-var_stream_map \'v:0,a:0,name:1080p v:1,a:1,name:720p v:2,a:2,name:360p\' \
-hls_segment_filename 'segment_%v_%05d.ts' 'manifest_%v.m3u8'
This command resizes the 1080p video that was uploaded to 1080p, 720p and 360p. For each variant a suitable (low size file with acceptable quality) bitrate is chosen. It is possible to change it, nothing will break. H.264 codec (libx264 encode) was chosen for video codec, in new versions of HLS you can use H.265 if you want. AAC codec was chosen for audio.
And with help of single_file
the segmentation is done through byte range instead of actual separate segments.
The second command is used after the first one whenever a new subtitle is uploaded.
ffmpeg -loglevel error -y -i input.ts -i ../sub1.srt \
-c:v copy \
-c:s webvtt \
-map 0:v \
-map 1:s \
-shortest \
-f hls \
-hls_flags +independent_segments+program_date_time+single_file \
-hls_time 6 \
-hls_playlist_type vod \
-hls_subtitle_path sub_eng.m3u8 \
-hls_segment_type mpegts \
-var_stream_map 'v:0,s:0,name:Spanish,sgroup:subtitle' \
-hls_segment_filename 'redundant_%v.ts' sub_%v.m3u8
sgroup
is a new feature implemented in ffmpeg to integrate subtitles into hls packaging. But because this feature is new, it does not have good functionality, therefore we use this feature only to process and segment the subtitle and the associated m3u8 (in this process the video is used as heartbeat for segmentation, turns out without the heartbeat the segmentation won't be perfect ). But we add the tag for this subtitle to master file manully with this package: (m3u8-parser)[https://github.com/miadabdi/m3u8-parser]
One other downside to this approach is, using the video as heartbeat will produce redundant extra identical-to-input videos, which we do not need. All of the names of these redundant videos start with redundant
so it would be easy to delete them afterwards.
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
Please make sure to update tests as appropriate.