nginx + shakaplayer + abr, is there a "easy" way?

1,833 views
Skip to first unread message

Rafael Linux User

unread,
May 9, 2017, 8:55:54 AM5/9/17
to Shaka Player Users
I have a working nginnx + rtmp module. I got to play in a basic way, an HLS and a DASH streaming. The players I implemented for this basic page were   http://cdn.dashjs.org/latest/dash.all.min.js  and  https://cdn.jsdelivr.net/hls.js/latest/hls.min.js
I create from another desktop PC a synthetic stream with:

ffmpeg -f lavfi -i 'testsrc=size=1280x720:rate=30' -f lavfi -i 'anoisesrc=color=pink' -c:v libx264 -profile:v baseline -level 3.0 -x264opts 'keyint=24:min-keyint=24:no-scenecut' -preset veryfast -maxrate 1984k -bufsize 3968k -vf "format=yuv420p" -g 60 -c:a aac -b:a 128k -ar 44100 -tune zerolatency -movflags +faststart -f flv "rtmp://10.162.20.20/rtmp_hls/bunny"
But in the end, the stream will come in MP4 from a camcorder.
It works even generating an HLS streaming (I only need to change "dash" to "hls" in the last parameter).
As I said, this is my basic configuration to develop a "simple" page that will show a live event monthly.
With this environment, I got a 6 to 10 seconds delay with "dash.js", but I want to use ABR, and discovered Shaka, that claims to be very good with low bandwidth.

Now, after reading and reading and trying, I must recognize that I'm lost. My nginx server with RTMP module was creating succesfully the manifest file. So I have now a lot of doubts:
- With Shaka player, do I need to demux previously my live stream?
- If I generate multibitrate thru ffmpeg (or M4BOX, but still not sure how), will I need ngingx to create automatically my MPD file?
- Is there any clear example to learn how to implement this scene?

Thank you to any who can light my complicated situation.

Joey Parrish

unread,
May 10, 2017, 6:39:39 PM5/10/17
to Shaka Player Users
Hi Rafael,

I'm not sure I understand your question about demuxing.  Are you asking if Shaka supports multiplexed streams?  The answer to that is, no, but we also don't prevent it.  Many browsers do not support multiplexed streams in MediaSource, and that is how Shaka does playback.  So you can try a multiplexed stream, and we won't stop you, but it probably won't work on every browser.

I don't know anything about ngingx.  The tools we use for packaging content come from our sister project, Shaka Packager.  The packager will create the MPD and does support live streams.  Of course, you can also use other tools.  There are several open-source options available, including gpac's tools and others.

If you don't multiplex your content, you may get better results, whether you're using ngingx, gpac, or Shaka on packaging side, or dash.js, hls.js, or Shaka on the player side.  This is because in the end, the browser has to consume the content via MediaSource, and multiplexed content is not universally supported in MediaSource implementations.

I suggest trying to get ffmpeg to output multiple streams at once.  You can have multiple outputs and map input streams to outputs.  So for example, input 0 stream 0 may be video, and input 0 stream 1 may be audio.  You would map input 0.0 to output 0.0, and input 0.1 to output 1.0.

You may not have to change packaging tools or players to make this work.  (Although we'd love to hear your feedback on Shaka Packager and Shaka Player if you decide to try them out.)

Does this help?
-Joey


--
You received this message because you are subscribed to the Google Groups "Shaka Player Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to shaka-player-users+unsub...@googlegroups.com.
To post to this group, send email to shaka-player-users@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/shaka-player-users/e8d14604-ec07-4ecc-868e-fdc3bcb62e21%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Rafael Linux User

unread,
May 11, 2017, 5:56:30 AM5/11/17
to Shaka Player Users

Hi Joey

In the first place, thank you for your complete answer.


I'm not sure I understand your question about demuxing.  Are you asking if Shaka supports multiplexed streams?  The answer to that is, no, but we also don't prevent it.  Many browsers do not support multiplexed streams in MediaSource, and that is how Shaka does playback.  So you can try a multiplexed stream, and we won't stop you, but it probably won't work on every browser.

Effectively, I was thinking that Shaka Player could play multiplexed streaming, despite I read that DASH needs a  demultiplexed stream. Now I need to know how to create a demultiplexed video (at various bitrates) + audio (at unique bitrate) with ffmpeg.

I don't know anything about ngingx.  The tools we use for packaging content come from our sister project, Shaka Packager.  The packager will create the MPD and does support live streams.  Of course, you can also use other tools.  There are several open-source options available, including gpac's tools and others.

I don't know too much (but nothing) about the Shaka Packager. My first idea was look for an server able to process rtmp and a GPL or similar DASH/HLS player. I discovered "dash.js"  and "hls.js" players that are easy to use. Then I found Shaka Player, that looks very good (and more if is supported by Google). However, for my neccesities (to stream a minimum of 1 live event monthly) the implementation os Shaka Player began to be a headache without results.

If you don't multiplex your content, you may get better results, whether you're using ngingx, gpac, or Shaka on packaging side, or dash.js, hls.js, or Shaka on the player side.  This is because in the end, the browser has to consume the content via MediaSource, and multiplexed content is not universally supported in MediaSource implementations.

I discovered that's a fact. I can play DASH/HLS in desktop (Linux/Win) and Android browsers, but not in iOS, I guess that it is for what you say about MSE is not supported universally.

I suggest trying to get ffmpeg to output multiple streams at once.  You can have multiple outputs and map input streams to outputs.  So for example, input 0 stream 0 may be video, and input 0 stream 1 may be audio.  You would map input 0.0 to output 0.0, and input 0.1 to output 1.0.

Yes, I read about it, and will try to get video and audio separated just after reply to your answer.

You may not have to change packaging tools or players to make this work.  (Although we'd love to hear your feedback on Shaka Packager and Shaka Player if you decide to try them out.)

I will read more about Shaka Packager and will give a new try to Shaka Player, but I must have a solution for tomorrow ... I wish I have more luck this time.

Does this help?

OF COURSE, your explanations help me a lot. I have more clear what I must do and you discovered me Shaka Packager. I'll tell you more about it if I progress a little more.
 
Rafael

Rafael Linux User

unread,
May 11, 2017, 7:00:42 AM5/11/17
to Shaka Player Users
Update: I didn't take into account that nginx make the hardest part of demux!!! That's the reason why it was working fine with hls.js and dash.js .

After take a look to Shaka Packager, it's a project too big for my neccesities. I'm not a day-to-day programmer (mostly PHP, HTML+CSS) so it's too much to solve my problem  ;)

Joey Parrish

unread,
May 11, 2017, 10:16:26 AM5/11/17
to Shaka Player Users
Shaka Packager has a command line tool, so you don't have to build on the C++ API.  But again, if you have other tools you like, you don't have to change to that.

With ffmpeg, you can output multiple bitrates at once.  You'll just apply different bitrate and/or scaling parameters to each output.

Would a sample command line be helpful?


--
You received this message because you are subscribed to the Google Groups "Shaka Player Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to shaka-player-users+unsub...@googlegroups.com.
To post to this group, send email to shaka-player-users@googlegroups.com.

Rafael Linux User

unread,
May 11, 2017, 10:54:09 AM5/11/17
to Shaka Player Users

Shaka Packager has a command line tool, so you don't have to build on the C++ API.  But again, if you have other tools you like, you don't have to change to that.

Well, really my problem now is that I have not many time to end this part of the project and only got results with the above mentioned tools. Of course, I would like to give Shaka Player/Packager another opportunity, cause I think it's a project more complete (and complex too, of course).

With ffmpeg, you can output multiple bitrates at once.  You'll just apply different bitrate and/or scaling parameters to each output.

I was just trying it, using this:

ffmpeg  -i rtmp://localhost:1935/live/$name
-c:a libfdk_aac -b:a 32k  -c:v libx264 -profile:v baseline -level 3.0 -x264opts 'keyint=24:min-keyint=24:no-scenecut' -b:v 128K -f flv rtmp://localhost:1935/rtmp_hls/$name_hls_low
-c:a libfdk_aac -b:a 64k  -c:v libx264 -profile:v baseline -level 3.0 -x264opts 'keyint=24:min-keyint=24:no-scenecut' -b:v 256k -f flv rtmp://localhost:1935/rtmp_hls/$name_hls_mid
-c:a libfdk_aac -b:a 128k -c:v libx264 -profile:v baseline -level 3.0 -x264opts 'keyint=24:min-keyint=24:no-scenecut' -b:v 512K -f flv rtmp://localhost:1935/rtmp_hls/$name_hls_hi
-c:a libfdk_aac -b:a 128k -c:v libx264 -profile:v baseline -level 3.0 -x264opts 'keyint=24:min-keyint=24:no-scenecut' -b:v 512K -f flv rtmp://localhost:1935/rtmp_dash/$name_dash  
             

But still can't get to see DASH/HLS video as previously got, before using "multiple encoding".
 

Would a sample command line be helpful?

Of course, any help will be wellcome!!!

Thank you!!

Joey Parrish

unread,
May 19, 2017, 3:18:20 PM5/19/17
to Shaka Player Users
I still think you will have more luck if you output separate streams for audio and video.  Here's an example:

#!/bin/bash

VIDEO_OPTS="-an -c:v libx264 -profile:v baseline -level 3.0 -x264opts keyint=24:min-keyint=24:no-scenecut -f $FORMAT"
AUDIO_OPTS="-vn -c:a libfdk_aac -f $FORMAT"

ffmpeg -i "$INPUT" \
  $VIDEO_OPTS -b:v 512k "$OUTPUT_VIDEO_HIGH" \
  $VIDEO_OPTS -b:v 256k "$OUTPUT_VIDEO_MID" \
  $VIDEO_OPTS -b:v 128k "$OUTPUT_VIDEO_LOW" \
  $AUDIO_OPTS -b:a 128k "$OUTPUT_AUDIO"

I put this in test.sh and called in like this for a VOD clip:

INPUT=input.mkv \
FORMAT=mp4 \
OUTPUT_VIDEO_HIGH=v-high.mp4 \
OUTPUT_VIDEO_MID=v-mid.mp4 \
OUTPUT_VIDEO_LOW=v-low.mp4 \
OUTPUT_AUDIO=a.mp4 \
./test.sh

ffmpeg created 4 files, each of which only contains a single stream.  Here's what ffmpeg says about the mapping:

Stream mapping:
  Stream #0:0 -> #0:0 (mpeg2video (native) -> h264 (libx264))
  Stream #0:0 -> #1:0 (mpeg2video (native) -> h264 (libx264))
  Stream #0:0 -> #2:0 (mpeg2video (native) -> h264 (libx264))
  Stream #0:1 -> #3:0 (ac3 (native) -> aac (native))

After transcoding, you would do this to package it as DASH:

packager \
  input=v-high.mp4,stream=video,output=v-high.mp4 \
  input=v-mid.mp4,stream=video,output=v-mid.mp4 \
  input=v-low.mp4,stream=video,output=v-low.mp4 \
  input=a.mp4,stream=audio,output=a.mp4 \
  --mpd_output dash.mpd



Here's an example using the same ffmpeg script, but creating a live stream and writing to UDP:

INPUT=long-input.mkv \
FORMAT=mpegts \
OUTPUT_VIDEO_LOW=udp://127.0.0.1:40001 \
OUTPUT_VIDEO_MID=udp://127.0.0.1:40002 \
OUTPUT_VIDEO_HIGH=udp://127.0.0.1:40003 \
OUTPUT_AUDIO=udp://127.0.0.1:40004 \
./test.sh 

For live, you would run the packager in parallel with ffmpeg.  It reads the streams from ffmpeg via UDP:

packager \
  'input=udp://127.0.0.1:40001,stream=video,init_segment=v-high-init.mp4,segment_template=v-high-$Number$.m4s,bandwidth=512000' \
  'input=udp://127.0.0.1:40002,stream=video,init_segment=v-med-init.mp4,segment_template=v-med-$Number$.m4s,bandwidth=256000' \
  'input=udp://127.0.0.1:40003,stream=video,init_segment=v-low-init.mp4,segment_template=v-low-$Number$.m4s,bandwidth=128000' \
  'input=udp://127.0.0.1:40004,stream=audio,init_segment=a-init.mp4,segment_template=a-$Number$.m4s,bandwidth=128000' \
  --mpd_output live.mpd



I highly recommend video and audio output be kept separate.  Whether you're doing DASH or HLS, VOD or live, you can use the same ffmpeg basic commands to do it.

Does this help?


--
You received this message because you are subscribed to the Google Groups "Shaka Player Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to shaka-player-users+unsub...@googlegroups.com.
To post to this group, send email to shaka-player-users@googlegroups.com.

Rafael Linux User

unread,
May 22, 2017, 5:18:02 AM5/22/17
to Shaka Player Users
I can say without doubt that your answers ALWAYS help.

You have reason when you say that is better to separate audio and video. In fact ngingx-rtmp module does it (m4v and m4a pieces) for each application created thru HLS/DASH directives. I forgot to mention it. However, your solution let me to avoid use one more HTTP service (ngingx) cause I have Apache working and don't need more.

I did the steps you wrote, but to "install" or "build" the Shaka packager is a headache, at least for me. I can't find it like a bin or a simple downloadable script. I wrote you this message after diving in Shaka packager documentation, but without success. I have not experiencie with "ninja" or "gclient" but I'm fighting with it. I think is the less I can do to thank your effort to help me.

I will report any advance about it.

Thank you

Joey Parrish

unread,
May 22, 2017, 2:37:15 PM5/22/17
to Shaka Player Users
If you are having trouble building the packager from source, try the releases page on github: https://github.com/google/shaka-packager/releases

It has binaries for Linux, OSX, and Windows.


--
You received this message because you are subscribed to the Google Groups "Shaka Player Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to shaka-player-users+unsub...@googlegroups.com.
To post to this group, send email to shaka-player-users@googlegroups.com.

Rafael Linux User

unread,
May 23, 2017, 6:27:28 AM5/23/17
to Shaka Player Users
Great!!! I didn't find that page before. I imagine it's better to compile - for performance - that to download and use the binary downloaded.

Anyway, just yesterday I got to compile it (I found more clear this post about it) but I didn't know where the binary packager was located. Today I found it and I'm just a step to make some test.

I think I'm near to get the "hard" part of the encoding and packaging steps.

I'll report any news about it.

Thank you again!

Joey Parrish

unread,
May 23, 2017, 1:00:52 PM5/23/17
to Shaka Player Users
Always happy to help!


--
You received this message because you are subscribed to the Google Groups "Shaka Player Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to shaka-player-users+unsub...@googlegroups.com.
To post to this group, send email to shaka-player-users@googlegroups.com.

Rafael Linux User

unread,
May 25, 2017, 7:30:55 AM5/25/17
to Shaka Player Users
I'm here again.

I got to use Shaka Packager using your examples, for a local file. However, I'm not able to make Shaka Player to show any video ("shaka.html") while DASH.js (see "primera_prueba.html") shows correctly the mpd generated with "packager".

Anyway, as I told you, my target is to show live events with lthe lowest latency. As you can see in my "test.sh" version, I use 2 seconds segments (GOP=48 and keyint=24). I noticed that all VIDEO files generated have the same size .... that's strange. So I have some questions related:
  • What am I missing on my "shaka.html" file? (the javascript file is located correctly and the server doesn't show any error).
  • Do I need to segment with ffmpeg or I only need to generate different streams at different rates and let packager to do the segmentation?
  • Is possible to generate a fMP4 stream and let Shaka Player (when I get to make it work) decide if use .mpd or .m3u8 stream?

Thank you in advance


shaka.html
primera_prueba.html
test.sh
Message has been deleted

Rafael Linux User

unread,
May 25, 2017, 12:31:59 PM5/25/17
to Shaka Player Users
Despite trying to guess what was happening with file sizes and trying to optimize ffmpeg tasks, I wrote this bash file, based on your fantastic one, and now I got video files with sizes related with the bitrates:

#!/bin/bash
echo
"-----------------------------"
INPUT
=$1
NOMBRE
=$(echo $1 | cut -f 1 -d '.')
FORMAT
=mp4
video_ext
=m4v
audio_ext
=m4a
OUTPUT_VIDEO_HIGH
="$NOMBRE"_high.$video_ext
OUTPUT_VIDEO_MID
="$NOMBRE"_mid.$video_ext
OUTPUT_VIDEO_LOW
="$NOMBRE"_low.$video_ext
OUTPUT_AUDIO
="$NOMBRE"_128k.$audio_ext

LIVE_OPTS
="-g 24 -keyint_min 24 -pix_fmt yuv420p  -preset veryfast -tune zerolatency -movflags +faststart -vsync passthrough "

 ffmpeg  
-y -i "$INPUT" $LIVE_OPTS -filter_complex '[0:v]yadif,split=3[out1][out2][out3];[0:a]aresample=44100[audio]' -map '[out1]' -b:v 512k "$OUTPUT_VIDEO_HIGH" -map '[out2]' -b:v 256k "$OUTPUT_VIDEO_MID" -map '[out3]' -b:v 128k "$OUTPUT_VIDEO_LOW" -map '[audio]' -b 128k "$OUTPUT_AUDIO"

But I still working on it.

Next step will be the live one.

Joey Parrish

unread,
May 25, 2017, 12:36:12 PM5/25/17
to Shaka Player Users
Based on your HTML, it looks like you're using Shaka Player v1.  Shaka Player v2 has been out for a long time now, with many improvements, new features, and bug fixes.  We are no longer maintaining v1, so you should upgrade to v2 before we dig any deeper into playback issues you are having.

Here's the upgrade guide from v1 to our latest release: https://v2-1-2-dot-shaka-player-demo.appspot.com/docs/api/tutorial-upgrade-v1.html

Since you're not using much of the API in v1, it may also be helpful to skip the upgrade guide and just look at the v2 API from scratch.  Here's the basic usage tutorial from our latest release: https://v2-1-2-dot-shaka-player-demo.appspot.com/docs/api/tutorial-basic-usage.html

As for MPD vs M3U8, only v2.1 supports HLS in the first place.  So you'd have to upgrade.  Second, there is no difference in terms of browser support.  If you have the exact same fMP4 files with both an MPD and M3U8 pointing to them, both should work equally in Shaka Player v2.1.


--
You received this message because you are subscribed to the Google Groups "Shaka Player Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to shaka-player-users+unsub...@googlegroups.com.
To post to this group, send email to shaka-player-users@googlegroups.com.

Rafael Linux User

unread,
May 29, 2017, 7:42:36 AM5/29/17
to Shaka Player Users
Hello again

I advanced a lot, in using packager, but however I did step backwards about shaka player.
About the shakaplayer, I tried to "compile" it downloading just now with "git", but after launching "python build/all.py" it showed these "npm" errors ....

.
184 files checked, no errors found.
npm ERR! Error: version not found: html...@0.9.14
npm ERR!     at /usr/share/npm/lib/cache/add-named.js:125:12
npm ERR!     at RegClient.get_ (/usr/share/npm/node_modules/npm-registry-client/lib/get.js:130:14)
npm ERR!     at RegClient.<anonymous> (/usr/share/npm/node_modules/npm-registry-client/lib/get.js:49:12)
npm ERR!     at evalmachine.<anonymous>:272:14
npm ERR!     at /usr/lib/nodejs/graceful-fs/graceful-fs.js:102:5
npm ERR!     at Object.oncomplete (evalmachine.<anonymous>:107:15)
npm ERR! If you need help, you may report this *entire* log,
npm ERR! including the npm and node versions, at:
npm ERR!     <http://github.com/npm/npm/issues>

npm ERR! System Linux 3.16.0-4-amd64
npm ERR! command "/usr/bin/nodejs" "/usr/bin/npm" "--prefix" "/home/shaka/shaka-player" "update"
npm ERR! cwd /home/shaka/shaka-player
npm ERR! node -v v0.10.29
npm ERR! npm -v 1.4.21
npm WARN engine karma-edg...@0.4.1: wanted: {"node":">=4"} (current: {"node":"0.10.29","npm":"1.4.21"})
npm WARN engine esp...@3.1.3: wanted: {"node":">=4"} (current: {"node":"0.10.29","npm":"1.4.21"})
npm WARN engine esco...@1.8.1: wanted: {"node":">=0.12.0"} (current: {"node":"0.10.29","npm":"1.4.21"})
npm WARN optional dep failed, continuing fsev...@1.1.1
npm WARN engine esp...@3.1.3: wanted: {"node":">=4"} (current: {"node":"0.10.29","npm":"1.4.21"})
npm WARN engine req...@2.79.0: wanted: {"node":">= 4"} (current: {"node":"0.10.29","npm":"1.4.21"})
npm WARN engine form...@2.1.4: wanted: {"node":">= 0.12"} (current: {"node":"0.10.29","npm":"1.4.21"})
npm WARN engine ha...@3.1.3: wanted: {"node":">=0.10.32"} (current: {"node":"0.10.29","npm":"1.4.21"})
npm WARN engine cryp...@2.0.5: wanted: {"node":">=0.10.40"} (current: {"node":"0.10.29","npm":"1.4.21"})
npm WARN engine bo...@2.10.1: wanted: {"node":">=0.10.40"} (current: {"node":"0.10.29","npm":"1.4.21"})
npm WARN engine ho...@2.16.3: wanted: {"node":">=0.10.40"} (current: {"node":"0.10.29","npm":"1.4.21"})
sh: 1: node: not found
npm WARN This failure might be due to the use of legacy binary "node"
npm WARN For further explanations, please read
/usr/share/doc/nodejs/README.Debian

npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR!     /home/shaka/shaka-player/npm-debug.log
npm ERR! not ok code 0

And I don't know what's going wrong. I should remember that I only need to play a  LIVE event, and if there is any way to put a Javascript and avoid compiling, it will be this easier.


On the "packager" side, I did a bash for VOD videos (for tests) and works fine. However, I have some doubts about how packager works.
If a use same "inputs" and "outputs"  (for m4v and m4a) filenames, it seems there is no problem about that. However, I created distinct output filenames for DASH and HLS  (prefixed with DASH_filename and HLS_filename) , but HLS m3u8 is not working (no video at all) while DASH mpd is working fine.

Can I make common m4v and m4a output files using for mpd and m3u8? (see attached bash file)

Thank you for all your help. In my case, I still see very far to get shakaplayer to work at least one time!!!  :(
VOD_empaquetar_MPD_y_M3U8.sh

Joey Parrish

unread,
May 30, 2017, 9:23:32 AM5/30/17
to Shaka Player Users
Hi Rafael,

I'm not sure, but regarding the errors you see from npm, you may need to upgrade npm.

But you could avoid compilation two ways:

Run Shaka Player in uncompiled mode.  See the debugging tutorial (https://shaka-player-demo.appspot.com/docs/api/tutorial-debugging.html) to learn how to set up the app in uncompiled mode.  In this mode, instead of build/all.py, you can just run build/gendeps.py to generate the files needed for uncompiled mode.

Another way to avoid compilation is just to use one of our precompiled releases.  You can install a pre-built version from npm:

npm install shaka-player

Or load the release directly from cdnjs in your script tag:

https://cdnjs.cloudflare.com/ajax/libs/shaka-player/2.1.2/shaka-player.compiled.js


As for generating dash and hls manifests at the same time from the same mp4s, I suggest you reach out to the Shaka Packager mailing list for help.


Does this help?
-Joey


--
You received this message because you are subscribed to the Google Groups "Shaka Player Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to shaka-player-users+unsub...@googlegroups.com.
To post to this group, send email to shaka-player-users@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages