Jump to content

Encode in HLS and Self-Host Videos


therebel
 Share

Recommended Posts

Hello,

I did a short video showing how to encode in hls using ffmpeg manually, then self-host your videos to feralhosting, and serve them to your jwplayer 8 (modified).

I fast forwarded the video, to show the basic steps, but you can see the timer on the bottom bar, the whole encode/upload, took less than 30min, for a seson with 19 episodes. (of course for a movie is faster...).

the tools used are all FREE (ffmpeg for encode, winscp for upload/manage files).

Feel free to ask question, im always open to help out (within limitis).

 

heres the link of the video, i hope you enjoy!

https://onionplay.org/fb/encode/hls.php (the video is hosted on facebook by the way).

for youtube lovers: youtu.be/laqqTtQ_Wyk

Edited by therebel
Link to comment
Share on other sites

rebuilt my whole site today then saw about this hehe..

its now pure nginx using easyengine to install wordpress and niginx

ive encoded some to hls siren being one and freed hehe take a looksee @therebel  https://tv-s.xyz/

the encode was done on server with the 

ffmpeg -i in.mp4 -c copy -map 0 -hls_time 3 -hls_list_size 0 -f hls out.m3u8

think i have it right .. :)

Link to comment
Share on other sites

WINDOWS

FOR /F "tokens=*" %G IN ('dir /b *.mp4') DO ffmpeg -i "%G" -c copy -map 0 -hls_time 3 -hls_list_size 0 -f hls "%~nG.m3u8"

FOR /F "tokens=*" %G IN ('dir /b *.mkv') DO ffmpeg -i "%G" -c copy -map 0 -hls_time 3 -hls_list_size 0 -f hls "%~nG.m3u8"
  
LINUX
  
for i in *.mp4; do ffmpeg -i "$i" -c copy -map 0 -hls_time 3 -hls_list_size 0 -f hls "${i%.*}.m3u8"; done

for i in *.mkv; do ffmpeg -i "$i" -c copy -map 0 -hls_time 3 -hls_list_size 0 -f hls "${i%.*}.m3u8"; done

You can do MKV too, but I always do prefer to encode to mp4, then split. MKV have strange mappings that sometime happened it went without audio or video was flickering after the split.

Link to comment
Share on other sites

6 hours ago, joez87m said:

question thou can this be done to mkv files or do they have to be convert to mp4 first then to hls ?

Also, I would suggest you to use 720p copies, as they are half in size compared to 1080p, and very watchable, so you could optimize the storage space better. Also, remember that, the commands to split in HLS arent perfect, they do their job, but its up to you to fine tuning yours. for example, for a 720p source, hls_time 3 , seems a good compromise, I would suggest you to test with both 2 and 4 and see whats better for you, meaning, smaller chunks, more often connections to the server, but better flow in video loading; doing hls_time 4 or 5 means bigger chunks, less connections to the server, but the users needs to have good connection.

test it!

Link to comment
Share on other sites

the encode i get are 720 for movies the tv are just standard mp4's rips by ion10 lol

oh and the one up at mo are hosted on the same as the wordpress im bringing on a file server later today so new stuff will be feed from thier so they was test to see how to encode hehe

Edited by joez87m
Link to comment
Share on other sites

  • 3 weeks later...
On 4/28/2018 at 11:19 AM, therebel said:

Hello,

I did a short video showing how to encode in hls using ffmpeg manually, then self-host your videos to feralhosting, and serve them to your jwplayer 8 (modified).

I fast forwarded the video, to show the basic steps, but you can see the timer on the bottom bar, the whole encode/upload, took less than 30min, for a seson with 19 episodes. (of course for a movie is faster...).

the tools used are all FREE (ffmpeg for encode, winscp for upload/manage files).

Feel free to ask question, im always open to help out (within limitis).

 

heres the link of the video, i hope you enjoy!

https://onionplay.org/fb/encode/hls.php (the video is hosted on facebook by the way).

for youtube lovers: youtu.be/laqqTtQ_Wyk

Pls can you guide me on how i can host my videos on Facebook too

Link to comment
Share on other sites

  • 1 month later...

Hi, 

FFMpeg is free.

in a post above, you can find the commands to split the mp4 files to hls.

all you need to do is having a good/fast storage to serve the .ts files.

(I would charge a small fee for the full install, if you have already the storage and the windows server).

cheers.

Link to comment
Share on other sites

  • 2 years later...
  • 11 months later...

if you are okay with using Powershell   this will   take any media file in the directory  and convert it to  HLS  and generate index file.   YOU WILL NEED TO CLEAN UP THE INDEX but other than that  fully automated which is nice    if you Copy/paste into  Notepad++  you can see which script is active and which isnt.   

 

$sw = [Diagnostics.Stopwatch]::StartNew()
$files = Get-ChildItem ${Get-Location}
$loco = Get-Location
$p1 = Join-Path -Path $loco -ChildPath "/out"
New-Item -ItemType Directory -Force -Path $p1



function lnCodeTransform {
	param( $String )
	switch ($String)
	{
		"jpn" {"jp"}
		"eng" {"en"}
		"esp" {"es"}
		"fra" {"fr"}
		"deu" {"de"}
		default {$String}
	}
}


function lnNameTransform {
	param( $String )
	switch ($String)
	{
		"jpn" {"Japanese"}
		"eng" {"English"}
		"esp" {"Spanish"}
		"fra" {"French"}
		"deu" {"German"}
		default {$String}
	}
}


foreach ($f in $files){	
	if ($f.Name -eq "out"){
		continue;
	}
	$p2 = Join-Path -Path $loco -ChildPath "/out/" | Join-Path -ChildPath $f
	New-Item -ItemType Directory -Force -Path $p2/audio
	New-Item -ItemType Directory -Force -Path $p2/video
	New-Item -ItemType Directory -Force -Path $p2/subtitle
	$sb = [System.Text.StringBuilder]::new();
	[void]$sb.AppendLine( '#EXTM3U' )
	[void]$sb.AppendLine( '#EXT-X-VERSION:3' )
	#[void]$sb.AppendLine( '#EXT-X-STREAM-INF:BANDWIDTH=800000,RESOLUTION=640x360' )
	#[void]$sb.AppendLine( '360p.m3u8' )
	

	New-Item -ItemType Directory -Force -Path $p2
	$resStr = ffprobe -v error -select_streams v:0 -show_entries stream=height -of csv=s=x:p=0 $f.FullName;
	$res = [convert]::ToInt32($resStr)
	$audioTracks = ffprobe $f.FullName -show_entries stream=index:stream_tags=language,title -select_streams a -of compact=p=0:nk=1 
	$audioTracks = $audioTracks.split("\r")
	foreach($audio in $audioTracks) {
		$splited = $audio.split("|");
		$ID = $splited[0]
		$audioName = $splited[1];
		$title = $splited[2];
		ffmpeg -i $f.FullName -ss 0 -y -map 0:$ID -start_number 0 -acodec aac -b:a 320k -ac 2 -f segment -segment_time 10 -segment_list_size 0 -segment_list out/$f/audio/audio_"$ID.m3u8" -segment_format mpegts out/$f/audio/"audio_$ID""_%d.ts"
		$name = lnNameTransform($audioName)
		$code = lnCodeTransform($audioName)
		[void]$sb.AppendLine( "#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID=`"aac`",LANGUAGE=`"$code`",NAME=`"$name ($title)`",DEFAULT=NO,AUTOSELECT=NO,URI=`"audio/audio_$ID.m3u8`"" )
	}
	$subTracks = ffprobe $f.FullName -show_entries stream=index:stream_tags=language,title -select_streams s -of compact=p=0:nk=1 
	$subTracks = $subTracks.split("\r")
	foreach($subtitle in $subTracks) {
		$splited = $subtitle.split("|");
		$ID = $splited[0];
		$subName = $splited[1];
		$title = $splited[2];
		ffmpeg -i $f.FullName -ss 0 -map 0:$ID -f segment -segment_time 10 -segment_list_size 0 -segment_list out/$f/subtitle/sub_"$ID.m3u8" -segment_format webvtt -scodec webvtt out/$f/subtitle/"sub_$ID%d.vtt"
		$name = lnNameTransform($subName)
		$code = lnCodeTransform($subName)
		[void]$sb.AppendLine( "#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID=`"subs`",LANGUAGE=`"$code`",NAME=`"$name ($title)`",FORCED=NO,AUTOSELECT=NO,URI=`"subtitle/sub_$ID.m3u8`"" )
	}

	[void]$sb.AppendLine( '#EXT-X-STREAM-INF:BANDWIDTH=1400000,CODECS="avc1.4d4015,mp4a.40.2",RESOLUTION=842x480,AUDIO="aac",SUBTITLES="subs"' )
	[void]$sb.AppendLine( 'video/480p.m3u8' )
	#ffmpeg -i $f.FullName -c:a copy -vf scale=w=640:h=360:force_original_aspect_ratio=decrease -c:a aac -ar 48000  -rc cqp -qp_p 0 -qp_i 1 -profile:v main -crf 20 -sc_threshold 0 -g 48 -keyint_min 48 -hls_time 4 -hls_playlist_type vod  -b:v 800k -maxrate 856k -bufsize 1200k -b:a 96k -hls_segment_filename out/$f/360p_%03d.ts out/$f/360p.m3u8 -vf scale=w=842:h=480:force_original_aspect_ratio=decrease -c:a aac -ar 48000 -gpu 1 -c:v h264_amf -rc cqp -qp_p 0 -qp_i 1 -profile:v main -crf 20 -sc_threshold 0 -g 48 -keyint_min 48 -hls_time 4 -hls_playlist_type vod -b:v 1400k -maxrate 1498k -bufsize 2100k -b:a 128k -hls_segment_filename out/$f/480p_%03d.ts out/$f/480p.m3u8 -vf  scale=w=1280:h=720:force_original_aspect_ratio=decrease -c:a aac -ar 48000 -gpu 1 -c:v h264_amf -rc cqp -qp_p 0 -qp_i 1 -profile:v main -crf 20 -sc_threshold 0 -g 48 -keyint_min 48 -hls_time 4 -hls_playlist_type vod -b:v 2800k -maxrate 2996k -bufsize 4200k -b:a 128k -hls_segment_filename out/$f/720p_%03d.ts out/$f/720p.m3u8 -vf  scale=w=1920:h=1080:force_original_aspect_ratio=decrease -c:a aac -ar 48000 -gpu 1 -c:v h264_amf -rc cqp -qp_p 0 -qp_i 1 -profile:v main -crf 20 -sc_threshold 0 -g 48 -keyint_min 48 -hls_time 4 -hls_playlist_type vod -b:v 5000k -maxrate 5350k -bufsize 7500k -b:a 192k -hls_segment_filename out/$f/1080p_%03d.ts out/$f/1080p.m3u8
	#ffmpeg -hwaccel auto -hwaccel_device 0 -i $f.FullName -c:v h264 -profile:v main -pix_fmt yuv420p -c:a aac -filter:v scale=360:640 -ar 48000  -rc cqp -qp_p 0 -qp_i 1 -profile:v main -crf 23 -sc_threshold 0 -g 48 -b:v 800k -maxrate 856k -bufsize 1200k -b:a 96k  -keyint_min 4 -start_number 0 -hls_time 10 -hls_playlist_type vod  -hls_list_size 0 -f hls -hls_segment_filename out/$f/360p_%03d.ts out/$f/360p.m3u8 
	#ffmpeg -hwaccel auto -hwaccel_device 0 -i $f.FullName -c:v h264 -profile:v main -pix_fmt yuv420p -c:a aac -filter:v scale=360:640 -start_number 0 -hls_time 10 -hls_list_size 0 -f hls -hls_segment_filename out/$f/360p_%03d.ts out/$f/360p.m3u8 
	#ffmpeg -i $f.FullName -c:v h264 -crf 23 -b:v 1200k -minrate 500k -maxrate 2100k -profile:v main -pix_fmt yuv420p -y -filter:v scale=-2:480 -map 0:v -start_number 0 -hls_time 10 -hls_list_size 0 -f hls -hls_segment_filename out/$f/video/480p_%03d.ts out/$f/video/480p.m3u8
	ffmpeg -hwaccel qsv -i $f.FullName -c:v h264_qsv -preset slow -global_quality 30 -look_ahead 1 -profile:v main -level:v 4.1 -rc:v vbr_hq -rc-lookahead:v 32 -pix_fmt yuv420p -y -filter:v scale=-2:480 -map 0:v -start_number 0 -hls_time 10 -hls_list_size 0 -f hls -hls_segment_filename out/$f/video/480p_%03d.ts out/$f/video/480p.m3u8
	If($res -ge 720) {
		#ffmpeg -i $f.FullName -c:v h264_qsv -crf 23 -b:v 2400k -minrate 1200k -maxrate 4200k -profile:v main -pix_fmt yuv420p -filter:v scale=-2:720 -map 0:v -start_number 0 -hls_time 10 -hls_list_size 0 -f hls -hls_segment_filename out/$f/video/720p_%03d.ts out/$f/video/720p.m3u8
		ffmpeg -hwaccel qsv -i $f.FullName -c:v h264_qsv -preset slow -global_quality 28 -look_ahead 1 -profile:v main -level:v 4.1 -rc:v vbr_hq -rc-lookahead:v 32 -pix_fmt yuv420p -filter:v scale=-2:720 -map 0:v -start_number 0 -hls_time 10 -hls_list_size 0 -f hls -hls_segment_filename out/$f/video/720p_%03d.ts out/$f/video/720p.m3u8
		[void]$sb.AppendLine( '#EXT-X-STREAM-INF:BANDWIDTH=2800000,CODECS="avc1.4d4015,mp4a.40.2",RESOLUTION=1280x720,AUDIO="aac",SUBTITLES="subs"' )
		[void]$sb.AppendLine( 'video/720p.m3u8' )
	}	
	If($res -ge 900) {
		#ffmpeg -i $f.FullName -c:v h264 -crf 30 -b:v 4800k -minrate 2000k -maxrate 8400k -profile:v main -pix_fmt yuv420p -filter:v scale=-2:1080 -map 0:v -start_number 0 -hls_time 10 -hls_list_size 0 -f hls -hls_segment_filename out/$f/video/1080p_%03d.ts out/$f/video/1080p.m3u8
		ffmpeg -hwaccel qsv -i $f.FullName -c:v h264_qsv -preset slow -global_quality 26 -look_ahead 1 -profile:v main -level:v 4.1 -rc:v vbr_hq -rc-lookahead:v 32 -pix_fmt yuv420p -filter:v scale=-2:1080 -map 0:v -start_number 0 -hls_time 10 -hls_list_size 0 -f hls -hls_segment_filename out/$f/video/1080p_%03d.ts out/$f/video/1080p.m3u8

		[void]$sb.AppendLine( '#EXT-X-STREAM-INF:BANDWIDTH=5000000,CODECS="avc1.4d4015,mp4a.40.2",RESOLUTION=1920x1080,AUDIO="aac",SUBTITLES="subs"' )
		[void]$sb.AppendLine( 'video/1080p.m3u8' )
	}
	If($res -ge 1200) {
		#ffmpeg -i $f.FullName -c:v h264 -crf 30 -b:v 4800k -minrate 2000k -maxrate 8400k -profile:v main -pix_fmt yuv420p -filter:v scale=-2:1080 -map 0:v -start_number 0 -hls_time 10 -hls_list_size 0 -f hls -hls_segment_filename out/$f/video/1080p_%03d.ts out/$f/video/1080p.m3u8
		ffmpeg -hwaccel qsv -i $f.FullName -c:v h264_qsv -preset slow -global_quality 24 -look_ahead 1 -profile:v main -level:v 4.1 -rc:v vbr_hq -rc-lookahead:v 32 -pix_fmt yuv420p -filter:v scale=-2:2160 -map 0:v -start_number 0 -hls_time 10 -hls_list_size 0 -f hls -hls_segment_filename out/$f/video/4k_%03d.ts out/$f/video/4k.m3u8

		[void]$sb.AppendLine( '#EXT-X-STREAM-INF:BANDWIDTH=5000000,CODECS="avc1.4d4015,mp4a.40.2",RESOLUTION=3840x2160,AUDIO="aac",SUBTITLES="subs"' )
		[void]$sb.AppendLine( 'video/4k.m3u8' )
	}
	
	$p3 = Join-Path -Path $p2 -ChildPath "/index.m3u8"
	#echo $index | Out-File -Encoding UTF8 -LiteralPath $p3
	echo $sb.ToString()
	[System.IO.File]::WriteAllLines($p3, $sb.ToString().Trim().replace("`r`n", "`n"))
}
$sw.Stop()
echo $sw.Elapsed

 

Link to comment
Share on other sites

  • 3 months later...
On 4/28/2018 at 7:19 AM, therebel said:

Hello,

I did a short video showing how to encode in hls using ffmpeg manually, then self-host your videos to feralhosting, and serve them to your jwplayer 8 (modified).

I fast forwarded the video, to show the basic steps, but you can see the timer on the bottom bar, the whole encode/upload, took less than 30min, for a seson with 19 episodes. (of course for a movie is faster...).

the tools used are all FREE (ffmpeg for encode, winscp for upload/manage files).

Feel free to ask question, im always open to help out (within limitis).

 

heres the link of the video, i hope you enjoy!

https://onionplay.org/fb/encode/hls.php (the video is hosted on facebook by the way).

for youtube lovers: youtu.be/laqqTtQ_Wyk

I'm looking for a server to upload adult videos. do you know any good ones? feralhosting doesn't have a problem with streaming?

Link to comment
Share on other sites

  • 1 year later...
 Share

  • Who's Online   0 Members, 0 Anonymous, 8 Guests (See full list)

    • There are no registered users currently online
×
×
  • Create New...