How to restream m3u8 with ffmpeg - ffmpeg

I use nginx rtmp and followig command:
ffmpeg -fflags +igndts -hide_banner -i https://ch.iptvmate.net/ec6e5689ffd6f9690102640bddd2f9e7.m3u8 -c copy -f hls -hls_time 4 -hls_flags append_list+delete_segments -hls_list_size 6 -hls_segment_filename 'hls/ch2/file%03d.ts' hls/ch2/playlist.m3u8
It streams but not live, it has recorded one period of the channel and this link streams this period again and again. Is the command correct? I just created the folder called ch2 and it is.

If you are trying to push stream as rtmp, HLS parameters are not required.
Simple way to re-stream via rtmp into nginx:
ffmpeg -fflags +igndts -hide_banner -i https://ch.iptvmate.net/ec6e5689ffd6f9690102640bddd2f9e7.m3u8 -c copy -f flv rtmp://127.0.0.1/live/stream
Afterwards, you can configure your live block in Nginx to have HLS.
application live {
live on;
hls on;
hls_path /tmp/hls;
}
Eventually, you would like to have chunks over HTTP:
location /hls {
# Serve HLS fragments
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /tmp;
add_header Cache-Control no-cache;
}
Try http://127.0.0.1/hls/stream.m3u8 when configuration is successful and ffmpeg is running.

Related

Webcam Stream With ffmpeg: UDP Stream remotely

I've a C920 HD camera connected to a Raspberry Pi 4 and my goal is to be able to access a stream of that camera anytime from my phone / laptop both connected to my network with a VPN.
Now, I managed to use ffmpeg like this:
ffmpeg -f v4l2 -input_format h264 \
-video_size 1920x1080 \
-i /dev/video4 \
-copyinkf -codec copy \
-f mpegts udp://192.168.1.10:5000?pkt_size=1316
On the computer 192.168.1.10 I can launch VLC go into "Network Transmission" and type udp://#:5000 in oder to watch the stream.
This is a single stream and from what I understand my RPi is just "shooting" the frames at that computer whatever it is connected or not, how can I have a proper stream (maybe rtmp?) that I can watch in multiple devices?
Please note: I'm using -copyinkf -codec copy in order to avoid transcoding and other operations that might result in a very high CPU usage. Can I do it this way also?
Thank you.
Nginx can be configured to host an RTMP video stream that will be used to play the stream coming from ffmpeg in all my devices. For this we need to install libnginx-mod-rtmp and configure nginx for RTMP:
apt install libnginx-mod-rtmp
Append the following to /etc/nginx/nginx.conf:
rtmp {
server {
listen 1935;
chunk_size 4096;
allow publish 127.0.0.1;
deny publish all;
application live {
live on;
record off;
}
}
}
systemctl restart nginx
Point ffmpeg to the nginx server:
ffmpeg -f v4l2 -input_format h264 \
-video_size 1920x1080 \
-i /dev/video4 \
-copyinkf -codec copy \
-f flv rtmp://127.0.0.1/live/stream
I also changed the output format to flv in order to improve compatibility with players.
Enjoy.

Re-broadcasting 24/7 stream with FFMPEG, using HLS. Original stream resets (probably), ffmpeg produces no HLS

I am rebroadcasting a live mp3 stream (probably it is using icecast - the admin requested me to re-broadcast it on another server). I am using ffmpeg for this task, using HLS playlist, to a public URL location.
It works! But sometimes (I mean once per day, mostly in the night), the m3u8 playlist file disappears or the re-broadcast is not working and I need to kill the ffmpeg process on the server and start it again.
ffmpeg -y -i "THE URL OF LIVE MP3" -f hls -hls_time 10 -hls_list_size 4 playlist.m3u8
I think there could be a problem with the original stream. But even if that happens, I need ffmpeg to "reload" the url of the stream. Is there any method to check and reset ffmpeg automatically?
Thank you so much!
Try to add reconnection flags. If issue is with input it can help:
ffmpeg \
-reconnect 1 -reconnect_at_eof 1 -reconnect_streamed 1 -reconnect_delay_max 2 \
-y -i "THE URL OF LIVE MP3" -f hls -hls_time 10 -hls_list_size 4 playlist.m3u8

How to save (record) rtsp stream to the disk storage without artifacts and missing seconds?

I need to save (record) rtsp stream to the disk storage.
I am using nginx-module and ffmpeg for it.
Here the config for enable recording:
rtmp {
live on;
hls on;
hls_fragment 5s;
server {
listen 1935;
application cam1 {
hls_path /tmp/cam1;
}
exec_static ffmpeg -rtsp_transport tcp -i rtsp://... -c copy -f flv rtmp://.../cam1/stream;
}
}
Config is creating the flv files, each duration of 5 second.
Then we need to merge all got files in one file by command:
ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.flv
After concated files we are got a problem. When previous 5 seconds end and start next 5 seconds we have artifacts and missing 0.5-1 second.
Please, get me help with saving rtsp stream without artifacts and missing seconds.
We are decided to exclude Nginx and build ffmpeg without format decoding. That’s helped us to fix our problem :
ffmpeg -rtsp_transport tcp -i "rtsp://..." -reconnect 1 \
-f segment -segment_format flv -segment_time 10 -segment_atclocktime 1 \
-reset_timestamps 1 -strftime 1 -avoid_negative_ts 1 \
-c copy -map 0 %Y%m%d-%H%M%S.flv

ffmpeg HTTP LIVE STREAMING remove old segments

Hello i Have a Live HTTP stream input for ffmpeg
i want to create HLS streaming im using ffmpeg to do this
ffmpeg -i http://127.0.0.1:4242/bysid/7275 -map 0 -codec:v libx264 -codec:a copy -f ssegment -segment_list playlist.m3u8 -segment_list_type hls -segment_list_size 10 -segment_list_flags +live -segment_time 10 out%03d.ts
i works fine i just want to delete the old segmens that are not shown in playlist.m3u8
segment_list_size 10
this will keep the last 10 in the playlist file i want to keep only these files on hard disk
You can use the recently added option to the HLS segmenter:
-hls_flags delete_segments
You will need to change your command to use the HLS segmenter rather than the stream segmenter by using -f hls instead of -f ssegment.
I've been using this option and it doesn't do exactly what you request, but rather it's implemented to be compliant with the HLS spec. See the ffmpeg documentation for more information: https://www.ffmpeg.org/ffmpeg-formats.html
USE
-segment_wrap 10
for wrap and rewrite segment files

How can we transcode live rtmp stream to live hls stream using ffmpeg?

I am trying to convert a live rtmp stream to hls stream on real time.
I got some idea after reading
http://sonnati.wordpress.com/2011/08/30/ffmpeg-%E2%80%93-the-swiss-army-knife-of-internet-streaming-%E2%80%93-part-iv/
i am able to convert the live rtmp stream to hls but not at run time. when i run the command and test for any hsl files (.m3u8 and .ts) i am not able to see but when i interrupt the command and check there i get the hls files as required.
I searched on google for solution but not able to get proper answer.
This is a short guide for HLS streaming with any input file or stream:
I am following user1390208's approach, so I use FFMPEG only to produce the rtmp stream which my server then receives to provide HLS. Instead of Unreal/Wowza/Adobe, I use the free server nginx with the rtmp module, which is quite easy to setup. This is how I do it in short: Any input file or stream -> ffmpeg -> rtmp -> nginx server -> HLS -> Client or more detailed:
input video file or stream (http, rtmp, whatever) --> ffmpeg transcodes live to x.264 + aac, outputs to rtmp --> nginx takes the rtmp and serves a HLS to the user (client).
So on the client side you can use VLC or whatever and connect to the .m3u8 file which is provided by nginx.
I followed this setup guide for nginx.
This is my nginx config file.
This is how I use ffmpeg to transcode my input file to rtmp:
ffmpeg -re -i mydirectory/myfile.mkv -c:v libx264 -b:v 5M -pix_fmt yuv420p -c:a:0 libfdk_aac -b:a:0 480k -f flv rtmp://localhost:12345/hls/mystream;
(the .mkv is 1080p with 5.1 sound, depending on your input, you should use lower bitrates!)
Where do you get the rtmp stream from?
A file? Then you can use exactly my approach.
Any server X with a stream Y? Then you have to change the ffmpeg command to:
ffmpeg -re -i rtmp://theServerX/yourStreamY -c:v libx264 -b:v 5M -pix_fmt yuv420p -c:a:0 libfdk_aac -b:a:0 480k -f flv rtmp://localhost:12345/hls/mystream;
or if your rtmp stream is already h.264/aac encoded, you could try to use the copy option in ffmpeg to stream the content directly to nginx.
As you see in my nginx config file:
My rtmp server has an "application" called "hls". That's the part that describes where nginx listens to ffmpeg's rtmp stream and that's why ffmpeg streams to rtmp://localhost:12345/hls/mystream;
My http server has the location /hls. This means in VLC I can connect to http://myServer:80/hls/mystream.m3u8 to access the HLS stream.
Is everything clear? Happy streaming!
Try this RTMP to HLS command line settings:
ffmpeg -v verbose -i rtmp://<host>:<port>/<stream> -c:v libx264 -c:a aac -ac 1 -strict -2 -crf 18 -profile:v baseline -maxrate 400k -bufsize 1835k -pix_fmt yuv420p -flags -global_header -hls_time 10 -hls_list_size 6 -hls_wrap 10 -start_number 1 <pathToFolderYouWantTo>/<streamName>.m3u8
There might be some delay in the HLS feed. However, it'll work.
As an update to this question, I've managed to complete the live transcoding from RTMP to HLS without the use of ffmpeg, how?
Well just by using the exact same nginx config file shared by user3069376 and being very careful about the paths that you are generating the .m3uh manifesto, the hls option within the RTMP module should take care of it.
As for video player the Video.Js worked like a charm o
If you already have the RTMP live stream ready and playing as HLS then you can simply add .m3u8 after the stream name and make RTMP link to http. For example you have RTMP link like this:
rtmp://XY.Y.ZX.Z/hls/chid
You have to just make the url like this:
http://XY.Y.ZX.Z/hls/chid.m3u8
and it will play smoothly in iOS. I have tried following code and it is working fine.
func setPlayer()
{
// RTMP URL rtmp://XY.Y.ZX.Z/hls/chid be transcripted like this http://XY.Y.ZX.Z/hls/chid.m3u8 it will play normally.
let videoURL = URL(string: "http://XY.Y.ZX.Z/hls/chid.m3u8")
let playerItem = AVPlayerItem(url: videoURL!)
let adID = AVMetadataItem.identifier(forKey: "X-TITLE", keySpace: .hlsDateRange)
let metadataCollector = AVPlayerItemMetadataCollector(identifiers: [adID!.rawValue], classifyingLabels: nil)
//metadataCollector.setDelegate(self, queue: DispatchQueue.main)
playerItem.add(metadataCollector)
let player = AVPlayer(playerItem: playerItem)
let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = self.view.bounds
self.view.layer.addSublayer(playerLayer)
self.player = player
player.play()
}
But it will be slow and laggy because of the high resolution video stream upload. If you make the resolution to low when uploading the video stream, it will work smooth in low bandwidth network as well.
Please note: It is not by FFMPEG as we have already RTMP running by
FFMPEG so I did like this.

Resources