No problem!
Hmm, then the only thing you can do is looking in your browser console log for errors. Otherwise we have to start guessing, which means game over ...
As this is for use on iOS (via an iPad) my options are limited.
I do however feel like I may have made a little progress, looking here ..
Using this..
<video src="http://example.com/path/mymovie.mp4" controls></video>
Which returns this (when used for the 4th stream’s UI widgets) - does this help matters ?
The html video
element supports only a few video formats, like e.g. the mp4 in your example. It doesn't support mpeg-ts streams, that is why that guy has developed the jsmpeg project. Your browser simply shows a play button which has been striked-through, to show you that he cannot play that format ...
Don't you have a possibility to open one of your url's with another Browser (chrome, firefox, ...) from another computer somehow? Because like I said, now we are just guessing what is going wrong ...
Interesting discussion,
To my understanding the .ts (transport stream) format cannot be played natively in a browser, it needs to be converted. I have some movies saved in that format that I recorded earlier with my Dreamboxes, satellite receievers that used that format for recording. The good part with this format is the high quality, it is uncompressed.
Anyway, I am testing this as well, so far not succesful, trying to play one of my old ts videos in the browser on my mac. Needless to say, VLC does it without problems
I had to put the jsmpeg.min.js in "/home/pi/.node-red/node_modules/node-red-dashboard/dist" to make the dashboard find it
I have put the video file into the defined http static folder ("/home/pi/Pictures")
So the page put in a ui template node looks just as simple as this
<script src="jsmpeg.min.js"></script>
<div class="jsmpeg" data-url="skizm.ts"></div>
In the chrome browser I get the following error when trying (the same error in mac/ios as in windows)
Maybe the best way is to use ffmpeg to convert the ts streams to a format that is supported by the browser. If it is possible to access the tuner by ssh (if it runs on Linux), the best could be to install ffmeg and make the conversion locally in the tuner. If not, maybe a RPi can do it?
It works.
The problem is the format, it needs to be mpeg1video container format with mp2 audio.
So it will need to be converted regardless.
Something like:
ffmpeg -i http://192.168.1.217:5004/tuner1/v4?transcode=internet240 -f mpegts -codec:v mpeg1video -bf 0 -codec:a mp2 -r 30 stream1.ts
This will copy the stream to the proper format without transcoding and can be included into a webpage with jsmpeg.min.js, however as you are already converting, it is easier to just output to mp4 and use that in a page without the need for jsmpeg.
OP wants 4 streams, this may become problematic in terms of CPU requirements.
Thanks all,
Maybe I’m missing something but, will this convert a live TV stream on the fly, or will everything have to be extracted, converted and then stored locally as a static file to play?
With HDHomerun, it has a number of transcode options,
Transcode Profiles:
• heavy: transcode to AVC with the same resolution, frame-rate, and interlacing as the original stream. For example 1080i60 → AVC 1080i60, 720p60 → AVC 720p60.
• mobile: trancode to AVC progressive not exceeding 1280x720 30fps.
• internet720: transcode to low bitrate AVC progressive not exceeding 1280x720 30fps.
• internet480: transcode to low bitrate AVC progressive not exceeding 848x480 30fps for 16:9 content, not exceeding 640x480 30fps for 4:3 content.
• internet360: transcode to low bitrate AVC progressive not exceeding 640x360 30fps for 16:9 content, not exceeding 480x360 30fps for 4:3 content.
• internet240: transcode to low bitrate AVC progressive not exceeding 432x240 30fps for 16:9 content, not exceeding 320x240 30fps for 4:3 content.
Being a quad tuner Homerun box, i’m assuming it’s spec’ed up to cope with producing 4 x internet240 streams. As I run Node Red and most things via my QNAP NAS and Docker - If I can create new supportable streams via an intermediary e.g ffmpg then I could give that a go.
The goal i set myself was to show the 4 separate streams and then maybe add option buttons to open natively in VLC at other quality levels (keep in mind that i’m primarily an iPad user, no PC, so I accept i’m making things way more complicated )
I found this online - any thoughts, I believe I need something similar, but working the other way ?
I’m continuing to try to get video streams via the Dashboard UI, the supported video capability of the iOS Safari browser does indeed seem to be my biggest limitation in my preferred design, (no video stream are playing yet) - but i’ll keep plugging away
Route (stream 5) showed some promise.. https://videojs.com/getting-started/
Ok, this looks very promising.
If anyone has time, would they be able to help/advise on what I should do? I have FFmpeg installed on my QNAP NAS, just need help to get this websever and javascript part set up?
It won't help you with iOS:
transcoders: {
'webm': {
ffmpegOptions: {
"-c:v": "libvpx",
"-c:a": "libvorbis",
"-f": "webm",
"-crf": "10"
},
contentType: "video/webm"
}
Perhaps you can change the options for h.264.
the node-ffmpeg-mpegts-proxy will work.
Thanks, this is a confusing area, mpeg.ts seems to be a pretty standard format, it’s just not supported via iOS / Safari, unless is ‘transmux’ it ?HLS seems to be a viable route, which confusingly reference mpeg.ts as it’s container.
I’m finding a few references online about tools that could do the conversion mpeg.ts to hls , but they seem to be paid for or subscription based. E.g
https://wmspanel.com/nimble
https://www.wowza.com/products/streaming-engine
My ideal solution is to have something that I could run locally on my NAS either via ffmpeg or perhaps something else within a Docker Container. The following shows some promise, just need to work it out.
Have you tried to convert a stream to HLS ?
You need to take this step by step.
This blog post gives a good idea for a commandline method (which in turn could also be executed from node-red)
Hi @bakman2,
Yep, that’s what i’m hoping to achieve, thanks for the link..
No luck so far..
What doesnt work ?
It’s seems when you create an HLS stream it creates it in segments and then you play them back via a playlist.
I’ve tried a variety of FFmpeg command lines some of which have shown promise - this being the best so far
ffmpeg -i "http://192.168.102.217:5004/auto/v1?" -c:v libx264 -crf 21 -preset veryfast \
-c:a aac -b:a 128k -ac 2 \
-f hls -hls_time 4 -hls_playlist_type event stream.m3u8
But the FFmpeg logs were full of errors and I could not work out how to reach the output playlist url, even though it’s specified in the request. (I assumed it would be something like 192.168.1.227/stream.m3u8 but that’s unfound.)
Here’s the output when the above command is run.
(Note: The no space error is a result of earlier tests which seem to have filled up its allocation of space)
ffmpeg version 3.3.6 Copyright (c) 2000-2017 the FFmpeg developers
built with gcc 4.9.2 (Debian 4.9.2-10)
configuration: --enable-cross-compile --arch=i686 --target-os=linux --disable-yasm --disable-static --enable-shared --enable-gpl --enable-libmp3lame --enable-libx264 --enable-libsoxr --enable-version3 --enable-nonfree --disable-decoder=ac3 --disable-decoder=ac3_fixed --disable-decoder=eac3 --disable-decoder=dca --disable-decoder=truehd --disable-encoder=ac3 --disable-encoder=ac3_fixed --disable-encoder=eac3 --disable-encoder=dca --disable-decoder=hevc --disable-decoder=hevc_cuvid --disable-encoder=hevc_nvenc --disable-encoder=nvenc_hevc --extra-ldflags='-L/root/daily_build/64_07/4.3.5/Model/TS-X73/build/RootFS/usr/local/medialibrary/lib -Wl,--rpath -Wl,/usr/local/medialibrary/lib' --extra-cflags='-I/root/daily_build/64_07/4.3.5/Model/TS-X73/build/RootFS/usr/local/medialibrary/include -D_GNU_SOURCE -DQNAP' --prefix=/root/daily_build/64_07/4.3.5/Model/TS-X73/build/RootFS/usr/local/medialibrary
libavutil 55. 58.100 / 55. 58.100
libavcodec 57. 89.100 / 57. 89.100
libavformat 57. 71.100 / 57. 71.100
libavdevice 57. 6.100 / 57. 6.100
libavfilter 6. 82.100 / 6. 82.100
libswscale 4. 6.100 / 4. 6.100
libswresample 2. 7.100 / 2. 7.100
libpostproc 54. 5.100 / 54. 5.100
[mpeg2video @ 0x12acea0] Invalid frame dimensions 0x0.
Last message repeated 22 times
[mpegts @ 0x129e5a0] Could not find codec parameters for stream 5 (Unknown: none ([11][0][0][0] / 0x000B)): unknown codec
Consider increasing the value for the 'analyzeduration' and 'probesize' options
[mpegts @ 0x129e5a0] Could not find codec parameters for stream 6 (Unknown: none ([11][0][0][0] / 0x000B)): unknown codec
Consider increasing the value for the 'analyzeduration' and 'probesize' options
[mpegts @ 0x129e5a0] Could not find codec parameters for stream 7 (Unknown: none ([5][0][0][0] / 0x0005)): unknown codec
Consider increasing the value for the 'analyzeduration' and 'probesize' options
[mpegts @ 0x129e5a0] Could not find codec parameters for stream 8 (Unknown: none ([5][0][0][0] / 0x0005)): unknown codec
Consider increasing the value for the 'analyzeduration' and 'probesize' options
Input #0, mpegts, from 'http://192.168.102.217:5004/auto/v1?':
Duration: N/A, start: 41533.689500, bitrate: N/A
Program 4164
Stream #0:0[0x65]: Video: mpeg2video (Main) ([2][0][0][0] / 0x0002), yuv420p(tv, top first), 704x576 [SAR 16:11 DAR 16:9], 25 fps, 25 tbr, 90k tbn, 50 tbc
Stream #0:1[0x66](eng): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, s16p, 256 kb/s
Stream #0:2[0x6a](eng): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, mono, s16p, 64 kb/s (visual impaired)
Stream #0:3[0x69](eng): Subtitle: dvb_subtitle ([6][0][0][0] / 0x0006)
Stream #0:4[0x98]: Audio: mp2 ([6][0][0][0] / 0x0006), 48000 Hz, stereo, s16p, 128 kb/s
Stream #0:5[0x1c21]: Unknown: none ([11][0][0][0] / 0x000B)
Stream #0:6[0x1c33]: Unknown: none ([11][0][0][0] / 0x000B)
Stream #0:7[0x1bbf]: Unknown: none ([5][0][0][0] / 0x0005)
Stream #0:8[0x1bc1]: Unknown: none ([5][0][0][0] / 0x0005)
Stream mapping:
Stream #0:0 -> #0:0 (mpeg2video (native) -> h264 (libx264))
Stream #0:1 -> #0:1 (mp2 (native) -> aac (native))
Press [q] to stop, [?] for help
-vol has been deprecated. Use the volume audio filter instead.
-vol is forwarded to lavfi similarly to -af volume=1.000000.
[libx264 @ 0x12cd3a0] using SAR=16/11
[libx264 @ 0x12cd3a0] using cpu capabilities: none!
[libx264 @ 0x12cd3a0] profile High, level 3.0
[hls @ 0x12cb660] Opening 'stream0.ts' for writing
Output #0, hls, to 'stream.m3u8':
Metadata:
encoder : Lavf57.71.100
Stream #0:0: Video: h264 (libx264), yuv420p, 704x576 [SAR 16:11 DAR 16:9], q=-1--1, 25 fps, 90k tbn, 25 tbc
Metadata:
encoder : Lavc57.89.100 libx264
Side data:
cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: -1
Stream #0:1(eng): Audio: aac (LC), 48000 Hz, stereo, fltp, 128 kb/s
Metadata:
encoder : Lavc57.89.100 aac
[hls @ 0x12cb660] Opening 'stream1.ts' for writing58 bitrate=N/A dup=34 drop=0 speed=1.34x
[hls @ 0x12cb660] Opening 'stream.m3u8.tmp' for writing
[hls @ 0x12cb660] Opening 'stream2.ts' for writing91 bitrate=N/A dup=34 drop=0 speed=1.33x
[hls @ 0x12cb660] Opening 'stream.m3u8.tmp' for writing
av_interleaved_write_frame(): No space left on devicebitrate=N/A dup=34 drop=0 speed=1.31x
[hls @ 0x12cb660] Opening 'stream.m3u8.tmp' for writing
Error writing trailer of stream.m3u8: No space left on device
frame= 383 fps= 32 q=26.0 Lsize=N/A time=00:00:14.86 bitrate=N/A dup=34 drop=0 speed=1.25x
video:1939kB audio:241kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
[libx264 @ 0x12cd3a0] frame I:3 Avg QP:19.10 size: 58434
[libx264 @ 0x12cd3a0] frame P:131 Avg QP:22.44 size: 11914
[libx264 @ 0x12cd3a0] frame B:249 Avg QP:27.32 size: 1529
[libx264 @ 0x12cd3a0] consecutive B-frames: 2.6% 13.6% 55.6% 28.2%
[libx264 @ 0x12cd3a0] mb I I16..4: 0.5% 24.6% 74.9%
[libx264 @ 0x12cd3a0] mb P I16..4: 0.9% 1.7% 0.7% P16..4: 47.1% 19.4% 13.5% 0.0% 0.0% skip:16.8%
[libx264 @ 0x12cd3a0] mb B I16..4: 0.1% 0.1% 0.0% B16..8: 13.7% 4.1% 0.6% direct: 4.1% skip:77.2% L0:29.7% L1:44.5% BI:25.8%
[libx264 @ 0x12cd3a0] 8x8 transform intra:41.8% inter:55.6%
[libx264 @ 0x12cd3a0] coded y,uvDC,uvAC intra: 78.4% 68.1% 26.6% inter: 15.8% 8.8% 0.8%
[libx264 @ 0x12cd3a0] i16 v,h,dc,p: 51% 24% 21% 4%
[libx264 @ 0x12cd3a0] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 39% 15% 30% 1% 2% 3% 2% 4% 4%
[libx264 @ 0x12cd3a0] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 41% 16% 12% 3% 5% 6% 4% 6% 7%
[libx264 @ 0x12cd3a0] i8c dc,h,v,p: 44% 18% 32% 6%
[libx264 @ 0x12cd3a0] Weighted P-Frames: Y:0.0% UV:0.0%
[libx264 @ 0x12cd3a0] kb/s:1105.31
[aac @ 0x12eb0e0] Qavg: 727.642
Conversion failed!
Resulting files on the server..
We don't give up.
Realtime streaming on iOS.
This assumes you have ffmpeg installed on the machine running node-red.
The flow:
[{"id":"665b41b9.be3548","type":"inject","z":"8a26c31b.4b3b38","name":"stream","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":200,"y":525,"wires":[["6b0a87ce.c579d"]]},{"id":"6b0a87ce.c579d","type":"function","z":"8a26c31b.4b3b38","name":"","func":"m = msg.payload \nif (m ==='kill'){\n return {kill:true}\n}\nelse{\nmsg.payload = `ffmpeg -fflags nobuffer \\\n-rtsp_transport tcp \\\n -i \"rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov\" \\\n -async 1 \\\n -copyts \\\n -acodec libmp3lame \\\n-ar 44100 \\\n-ac 2 \\\n -vcodec libx264 \\\n -profile:v baseline \\\n -preset:v superfast\\\n -movflags frag_keyframe+empty_moov \\\n -an \\\n -hls_flags delete_segments+append_list \\\n -f segment \\\n -segment_list_flags live \\\n -segment_format mpegts \\\n -segment_list /home/administrator/.node-red/stream/index.m3u8 \\\n -segment_list_type m3u8 \\\n /home/administrator/.node-red/stream/%d.ts`\n \n return msg\n}\n","outputs":1,"noerr":0,"x":375,"y":550,"wires":[["838014a2.2b358"]]},{"id":"838014a2.2b358","type":"exec","z":"8a26c31b.4b3b38","command":"","addpay":true,"append":"","useSpawn":"true","timer":"","oldrc":false,"name":"","x":525,"y":550,"wires":[["8078bcc1.0e734"],["d71455f0.a59c38"],["13887079.10e7c"]]},{"id":"8078bcc1.0e734","type":"debug","z":"8a26c31b.4b3b38","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":700,"y":500,"wires":[]},{"id":"d71455f0.a59c38","type":"debug","z":"8a26c31b.4b3b38","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":700,"y":550,"wires":[]},{"id":"13887079.10e7c","type":"debug","z":"8a26c31b.4b3b38","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":700,"y":600,"wires":[]},{"id":"1be68620.5f0482","type":"inject","z":"8a26c31b.4b3b38","name":"kill","topic":"","payload":"kill","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":200,"y":600,"wires":[["6b0a87ce.c579d"]]},{"id":"25dd9106.f7e8fe","type":"ui_template","z":"8a26c31b.4b3b38","group":"bd835a7f.a3cb1","name":"","order":0,"width":0,"height":0,"format":"<video id=\"video-player\" controls preload=\"none\">\n <source src=\"http://10.0.0.6:1880/index.m3u8\" type=\"application/x-mpegURL\">\n</video>","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":410,"y":450,"wires":[[]]},{"id":"bd835a7f.a3cb1","type":"ui_group","z":"","name":"Default","tab":"6f70ef77.c1505","disp":true,"width":"6","collapse":false},{"id":"6f70ef77.c1505","type":"ui_tab","z":"","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]
There are a couple of things that require some changes to make this work:
- The function node contains paths, you will need to change those to your own.
- In the node-red
settings.js
file you need to configurehttpStatic
to match the path used in the function node - In the template node, change the url (ip-address/path) to your own matching the
httpStatic
path
This example uses bigbuckbunny, for your stream, remove -rtsp_transport tcp \
and change the rtsp://xx
to your own http://zz/xx
No we don’t !!!
Thanks so much @bakman2
My challenge now will be to map this correctly to my mpeg.ts HDHomerun feed , and change the configuration as I run Node Red from within a Docker Container and ffmpeg is installed on the host server..
And just so I’m clear, my httpstatic will be updated to "http://192.168.102.217:5004/auto/v1?" ?
as I run Node Red from within a Docker Container
You just don't want to make this work, do you ?
Docker will be problematic. It implies that you have to make a new container that both includes ffmpeg and node-red. Or separate containers with links between the 2.
You can ofcourse copy the code from the function node to a stream.sh
file, chmod +x stream.sh
file and execute it, it will realtime transcode. Only thing left is to host the output file on a webserver. Something like python can do this easily.
Or just run node-red natively