Skip to content

miadabdi/video-sharing-platform

Repository files navigation

Video-Sharing-Platform

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.

Installation

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.

Step 1: install FFMPEG

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

Step 2: Fill out the env file

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.

Step 3: Compile nginx and nginx-rtmp-module together

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.

Step 4: Replace nginx config with the one provided in project

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.

Step 5: Open 80, 443, 1935 port

Open these ports, nginx will use 80 and 443 to serve content. And it will user 1935 for rtmp.

Step 6: Change default nginx user.

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).

Step 7: Install packages and run the app

npm install
npm start

Details

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.

Commands

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.

Contributing

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.

License

GNU General Public License v3.0

About

This is a video sharing platform. Capable of sharing videos (video on-demand) and live streaming to mass audiance.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published