..
I want to record from a source... and the same time... send some "ms" / chuncks / frames (i don't know what exactly) to other ip (may be using mqtt) and from the other side playing those somehow... until the source stop sending
Stream with my way..
(ps: the communication way is not a problem... the problem is how to get chunks ... and how to play them)
I imagine that you have a video file that you want to convert to MP4 using FFmpeg, and you do not want to save the output data to the disk, you rather want to transfer it
directly to another program. Perhaps the file is large and you want to send it elsewhere without waiting for the end of the entire conversion or without saving it to the disk.
Something simple, like the following of the command, unfortunately does not work:
FFmpeg -f dhav -i '
http://192.168.2.100/somefile.dav' -c copy -f mp4
The standard MP4 file structure consists of data fragments called "atoms".
Two of them are important:
1. mdat - type containing multimedia paths (such as audio or video);
2. moov - type containing additional metadata (such as information about the duration of the film, codecs, etc.).
It is important that each atom must determine its size in the header. In mdat, however, the size is not known until completely discharged.
So FFmpeg begins to write a mate atom with a size set to zero, then fills it back and finally leads the moov atom.
However, you can't look back on the pipe - that's what I find the problem.
An alternative to the standard MP4 structure is "fragmentary MP4".
His moov atom is at the beginning of the file and may lack some fields (for example, the duration of the film).
The songs are divided into fragments, each of which creates a pair of moof and mdat atoms (moof atom contains metadata on a mdat fragment).
These fragments are small enough that FFmpeg can keep them in memory, wait for them to be complete, released moof and mdat atoms and repeat for the next.
In the case of fragmentary MP4, there is no need to search in the output stream,
To create such a file, FFmpeg must receive one additional option:
FFmpeg -f dhav -i '
http://192.168.2.100/somefile.dav' -c copy -movflags 'frag_keyframe+empty_moov' -f mp4
The movflags parameter specifies that you want to create a fragmentary MP4 file in which each key cage
It launches a new fragment, moov atom is reset, followed by moofs and mdats fragmentation.
In practice, fragmentary MP4 files are less compatible.
For example, the built-in Windows video player is confused with the empty moov atom reports zero duration and the strap
search is useless, although interestingly plays files.
Returning to your question in the thread:
The first thing you should know about FFmpeg is to use a copy of the codec such as -c:v copy then you can't change the movie,
e.g. segment time, size or anything else we need to use FFmpeg to generate HLS playback list formatted as fmp4.
When playing the segmented MP4 file, an init file will always be available and then video segments.
FFmpeg -i 0000.mp4 -f hls -hls_segment_type fmp4 -c:v copy playlist.m3u8
It will generate a playlist file containing a file list, init.mp4 file and video segments.
Once you have this list and files in the appropriate format, you can use any selected method,
To deliver them to a multimedia source player.
Remember that if you want to change the size of the segments, you need to re-code the video with a codec such as libx264.
In addition, if you want to see available options for mukser HLS, run FFmpeg -h muxer=hls and give you some details.
The FFmpeg CMD command that I gave you generates the defragmented MP4 files that are intended to play in the extension of the multimedia source.
If you connect any single fragment of the m4 file with init.mp4, you will receive a complete MP4 file that can be reproduced by a multimedia source.
The m4s file simply contains mdat data, i.e. actual video cages. init.mp4 file contains header information that contains such elements,
like width, height, codec, ... etc.
When using the extension of the multimedia source, you first send the init.mp4 file
for a multimedia source player, followed by all fragments of m4s.
In this way you manufacture segments of complete MP4 files instead of fragments of MP4 files.
Looking for a way to get an applemented MP4 file, I found the only way that has worked for me so far:
ffmpeg -y -i 0000.mp4 -c:a libfdk_aac -ac 2 -ab 128k -c:v libx264 -x264opts 'keyint=24:min-keyint=24:no-scenecut' -ss 0 -t 30 v0.mp4 // get the first 30 seconds of the video
./mp4fragment v0.mp4 fragmented-v0.mp4
or
ffmpeg -i ./myvideo.mp4 -c:a libfdk_aac -ac 2 -ab 128k -c:v libx264 -x264opts keyint=24:min-keyint=24:no-scenecut -f segment -segment_time 10 ./video/%01d.mp4
1. Division of the film at regular intervals:
- In general, we divide the film into many parts to extract smaller fragments of this film.
At the beginning, we will divide the film into several parts, each of which will last exactly the same amount of time:
ffmpeg -i 0000.mp4 -acodec copy -f segment -segment_time 10 -vcodec copy -reset_timestamps 1 -map 0 output_time_%d.mp4
This command downloads the input video file, 0000.mp4, and divides it into 10 parts.
We will understand every option:
-i specifies the input file, in our case, 0000.mp4
-acodec copy sets the audio codec for the output to copy, which means the audio stream will be copied without re-encoding
-f segment sets the format to segment
-segment_time 10 specifies the duration of each segment to 10 seconds
-vcodec copy sets the video codec for the output to copy, which means the video stream will be copied without re-encoding
-reset_timestamps 1 resets timestamps for each segment and creates segments with continuous timestamps
-map 0 maps all the streams from input to the output
output_time_%d.mp4 defines the naming pattern for the output files, where %d in the naming pattern is a placeholder for a numeric index
As a result of this command, we receive three (3) input video segments, 0000.mp4,
With a approximate duration of 10 seconds each.
However, it often happens that not all resulting segments last exactly 10 seconds.
The reason for this is the complex nature of the video file. Many factors are at stake,
Including key frames, audio-video synchronization and variable number of frames per second.
Therefore, re -encoding the video before segmentation can be used as a better approach
enabling more accurate control of the duration of the segment.
2. Division by re-coding:
- video coding may result in an increase or decrease in size,
Depending on the quality of the input video and libraries, the codecs used for re-coding.
To start with, we will encode the video again with FFmpeg, and then divide them into many parts:
ffmpeg -i 0000.mp4 -c:v libx264 -c:a aac -strict experimental -b:a 192k -force_key_frames "expr:gte(t,n_forced*10)" -f segment -segment_time 10 -reset_timestamps 1 -map 0 output_part_%d.mp4
First of all, this command re-encodes the input video input using audio and video codecs.
Secondly, it forces cages of key 10 second intervals.
Finally, he divides the video into parts, each of which lasts for 10 seconds.
We will understand the new parameters used in this command:
-c:v libx264 sets the video codec to libx264
-c:a aac sets the audio codec to AAC
-strict experimental is needed when using the AAC audio codec
-b:a 192k sets the audio bitrate to 192 kbps
-force_key_frames forces keyframes at regular intervals set by the following expression
"expr:gte(t,n_forced*10)" forces a keyframe every 10 seconds (time t)
3. Video division at regular intervals of key frames:
- Like sharing at regular intervals, sharing at regular intervals of key frames can be difficult.
So, we will divide the video file, coding it again:
ffmpeg -i 0000.mp4 -c:v libx264 -c:a aac -strict experimental -b:a 192k -force_key_frames "expr:gte(n,200*trunc(t/200))" -f segment -segment_frames $(seq 200 200 600 | paste -sd "," -) -reset_timestamps 1 -map 0 output_partf_%d.mp4
This command is effectively divided by the input video file, 0000.mp4, in each 200 key frames.
Parameter -force_key_frames "expr:gte(n,200*trunc(t/200))" It ensures that the key cage is forced every 200 frames.
Let's take a closer look at:
gte(n,200*trunc(t/200)) The expression assesses whether the current frame number N is greater or equal to the calculated key cage index
200 * trunc(t/200) defines the key cage index, where T represents the time in seconds.
With the -segment_frames option, we can specify the frame numbers at which to split the video.
In the above command, we used seq to generate a sequence of numbers from 200 to 600
in increments of 200 and the paste command to join the numbers with a comma separator.
We can also manually specify frame numbers (i.e., 200, 400, 600) instead of generating them using SEQ in the above order, achieving the same result.
In addition, we can force the key frames using any cage index, which is a factor in the target interval of key frames, in this case, 200.
4. Extracting the duration of the film:
- Because the duration of the video during chronological time may be inconsistent, we can use both seconds and cages as video measurements.
4.1. Chronological units:
- First, let's go find the duration from one of the first parts, we divided with help ffprobe:
ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 output_part_1.mp4 10.000000
-v error sets the verbosity level to error
-show_entries format=duration specifies the information to be displayed, in our case, the duration of the multimedia file
-of default=noprint_wrappers=1:nokey=1 specifies the output format
output_part_1.mp4 is the name of the input multimedia file
Similarly, we can check the duration of each of the split parts with ffprobe.
4.2. Frame:
- Now, let’s find the total number of frames in one of the keyframe-split videos using ffprobe:
ffprobe -v error -select_streams v:0 -show_entries stream=nb_frames -of default=nokey=1:noprint_wrappers=1 output_partf_0.mp4 200
So the first divided part has 200 frames. In this command, -select_streams v:0 defines and selects a video stream with an index 0.
The -show_entries stream=nb_frames The option specifies the information to be displayed, i.e. the total number of frames available in the input video file.
Similarly, we can use ffprobe to find the total number of frames in each of the divided films by changing the input file name.
In this description above, I tried to tell you how to divide the film into many parts using FFmpeg.
I am also asking for your understanding in translation into my weak English
I have that this extensive material will help you at least in a small part in your task.