I have a ts file, which is created by encoding raw yuv data using x264enc and muxing it with mpegtsmux.
And this file contains more than one stream. For example it may contain two video streams, or it may contain two video and one text stream like that.
It is of 25 fps, and 720X576 resolution. I would like to change it's fps to say 10, and all the three streams must present in the new ts file also.
Is there any pipeline for this in gstreamer? or any command in ffmpeg? How can i do this?
I don't think that this is possible in GStreamer. At least is not straightforward. However, it should be possible with ffmpeg as long as all the sequences in the file can be discovered correctly.
From the wiki of ffmpeg, map option (https://trac.ffmpeg.org/wiki/Map):
The "map" command basically means "include this stream into the
immediately following OUTPUT file."
Using map option it is possible to re-encode the video stream that you want and keep untouched the others.
Using input.ts file as an example with 2 different video streams and some audio streams, the way to follow should be the next:
ffmpeg -i input.ts -map 0:0 -map 0:2 -map 0:3 -map 0:4 -map 0:23 -map 0:10 -map 0:14 -c:v:0 mpeg2video -r:v:0 10 -c:v:1 copy -c:a copy outputmini.ts
Note that the video streams are 0:0 and 0:23. The first video stream (mpeg2) is re-encoded to 10 fps whereas the 0:23 video stream (x264) is just copied to the output. Remember that if there is some unknown stream in the .ts file you may need to add -ignore_unknown flag.
As specified in the link from ffmpeg, the output stream order is specified in the command execution in the map option placement order. With -c:v:0 mpeg2video option, we select the first output video stream and re-encoding codec, while the -r:v:0 10 option puts the first video stream frame rate to 10 fps. The other options from the command line copies the input stream to output with the same parameters.
ffmpeg outputs next:
Output #0, mpegts, to 'outputmini.ts':
Metadata:
encoder : Lavf57.41.100
Stream #0:0: Video: mpeg2video (Main), yuv420p, 640x576 [SAR 6:5 DAR 4:3], q=2-31, 200 kb/s, 10 fps, 90k tbn, 10 tbc
Metadata:
encoder : Lavc57.50.100 mpeg2video
Side data:
cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: -1
Stream #0:1(spa): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, 192 kb/s
Stream #0:2(qaa): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, 192 kb/s
Stream #0:3(spa): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, mono, 96 kb/s (visual impaired)
Stream #0:4: Video: h264 ([27][0][0][0] / 0x001B), yuv420p(tv, bt709), 1280x720 [SAR 1:1 DAR 16:9], q=2-31, 50 fps, 50 tbr, 90k tbn, 90k tbc
Stream #0:5(spa): Audio: eac3 ([6][0][0][0] / 0x0006), 48000 Hz, stereo, 256 kb/s
Stream #0:6(spa): Audio: eac3 ([6][0][0][0] / 0x0006), 48000 Hz, mono, 64 kb/s (visual impaired)
Stream mapping:
Stream #0:0 -> #0:0 (mpeg2video (native) -> mpeg2video (native))
Stream #0:2 -> #0:1 (copy)
Stream #0:3 -> #0:2 (copy)
Stream #0:4 -> #0:3 (copy)
Stream #0:23 -> #0:4 (copy)
Stream #0:10 -> #0:5 (copy)
Stream #0:14 -> #0:6 (copy)
The desired output is achieved.
However, even though I'm not sure this could be done, I would get a glimpse to tsMuxeR appllication (http://www.videohelp.com/software/tsMuxeR). It is a very powerful tool to this kind of tasks.
Related
I have an input MPEG TS file 'unit_test.ts'. This file has following content (shown by ffprobe):
Input #0, mpegts, from 'unit_test.ts':
Duration: 00:00:57.23, start: 73674.049844, bitrate: 2401 kb/s
Program 1
Metadata:
service_name : Service01
service_provider: FFmpeg
Stream #0:0[0x31]: Video: h264 (Main) ([27][0][0][0] / 0x001B), yuv420p(progressive), 852x480 [SAR 640:639 DAR 16:9], Closed Captions, 59.94 fps, 59.94 tbr, 90k tbn, 119.88 tbc
Stream #0:1[0x34](eng): Audio: ac3 ([129][0][0][0] / 0x0081), 48000 Hz, 5.1(side), fltp, 448 kb/s
Stream #0:2[0x35](spa): Audio: ac3 ([129][0][0][0] / 0x0081), 48000 Hz, stereo, fltp, 192 kb/s
I want to convert it into another MPEG TS file. Requirement is that the Video stream of the input should be directly copied to the output whereas ALL the audio streams should be transcoded "aac" format.
I tried this command:
ffmpeg -i unit_test.ts -map 0 -c copy -c:a aac maud_test.ts
It converted it into 'maud_test.ts' with following contents (shown by ffprobe)
Input #0, mpegts, from 'maud_test.ts':
Duration: 00:00:57.25, start: 1.400000, bitrate: 2211 kb/s
Program 1
Metadata:
service_name : Service01
service_provider: FFmpeg
Stream #0:0[0x100]: Video: h264 (Main) ([27][0][0][0] / 0x001B), yuv420p(progressive), 852x480 [SAR 640:639 DAR 16:9], Closed Captions, 59.94 fps, 59.94 tbr, 90k tbn, 119.88 tbc
Stream #0:1[0x101](eng): Audio: aac (LC) ([15][0][0][0] / 0x000F), 48000 Hz, 6 channels, fltp, 391 kb/s
Stream #0:2[0x102](spa): Audio: aac (LC) ([15][0][0][0] / 0x000F), 48000 Hz, stereo, fltp, 133 kb/s
So it appeared as if the command worked....However when I play the maud_test.ts file in vlc player I can see both audio streams listed in the menu; but Stream 1 (eng) remains silent............whereas Stream 2 (spa) has proper audio. (Original TS file has both audio streams properly audible)
I have tried this with different input files and have seen that same problem occurs in each case.
What that I am doing is not right?
How should I get this done? (I can write explicit stream by stream map and channel arguments to get that done; however I want the command line to be generic, in that the input file could be having any configuration with one Video and several Audios with different formats. The configuration will not be known beforehand.)
I have a txt file which contains several videos:
file '01.mp4' # No audio, only video
file '02.mp4' # Video with audio
...
All my videos are using same video codecs:
Stream #0:0[0x1](und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 720x1280, 3167 kb/s, 30 fps, 30 tbr, 15360 tbn (default)
And all my video that contains audio are these codecs:
Stream #0:1[0x2](und): Audio: aac (HE-AAC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 43 kb/s (default)
I tried to add silent audio using:
ffmpeg -f lavfi -i anullsrc=channel_layout=stereo:sample_rate=44100 -i 01.mp4 -c:v copy -c:a aac -shortest 01-silentaudio.mp4
But when concatening all my videos, it results in no audio for all videos.
What should I do?
Maybe I can reencode all my video to a specific codec, including my video without sound, in order to have the same codecs for all? What do you think?
Thank you
I'm converting some old videos to play on my Roku via a dlna server. I'm trying to understand the MP4 container better to optimize conversions. I have an ogm video:
Duration: 01:00:38.22, start: 0.000000, bitrate: 1056 kb/s
Stream #0:0: Video: mpeg4 (XVID / 0x44495658), yuv420p, 576x324 [SAR 1:1 DAR 16:9], 23.98 fps, 23.98 tbr, 23.98 tbn, 23.98 tbc
Stream #0:1(English): Audio: aac, 48000 Hz, stereo, fltp, 74 kb/s
Stream #0:2(Japanese): Audio: aac, 48000 Hz, stereo, fltp, 73 kb/s
Stream #0:3(English): Subtitle: text
From what I understand, MP4 container can contain MP4 video and aac audio. I used
-c:a copy -c:v copy
And it worked, but the video won't play. Obviously something's wrong. What I don't understand is why, the video looks like it's MP4 and the audio is aac. My guess is it's the Xvid but why?
Thank you.
Todd
MP4 is only the container but your right MP4 usually contain AAC audio and MPEG4 video. Your input file seems to be mpeg4 Xvid which is a mpeg4 derived codec but might not be supported by Roku.
Try change -c:v copy to -c:v h264 to use a more common MPEG4 based video codec.
What I want is straightforward: wrap H.264 video stream into a FLV container. However, ffmpeg just decode the input stream and pack raw video stream into FLV. The details are described below:
The input stream is captured from a hardware-encoder video camera, and the FLV will be sent to some video server. Firstly I used following command:
$ ffmpeg -framerate 15 -s 320x240 -i /dev/video1 -f flv "rtmp://some.website.com/receive/path"
However, the resultant stream is suspicious. The watching side don't get any H.264 thing. Then I made a test by writing output to local files.
1: Read raw stream, encode by h264_omx, write to FLV file:
$ ffmpeg -framerate 15 -s 320x240 -i /dev/video0 -codec h264_omx -f flv raw_input_h264_omx.flv
......
Input #0, video4linux2,v4l2, from '/dev/video0':
Duration: N/A, start: 194017.870905, bitrate: 18432 kb/s
Stream #0:0: Video: rawvideo (YUY2 / 0x32595559), yuyv422, 320x240, 18432 kb/s, 15 fps, 15 tbr, 1000k tbn, 1000k tbc
Stream mapping:
Stream #0:0 -> #0:0 (rawvideo (native) -> h264 (h264_omx))
......
2: Read H264 stream, write to FLV file:
$ ffmpeg -framerate 15 -s 320x240 -i /dev/video1 -f flv h264_input.flv
......
Input #0, video4linux2,v4l2, from '/dev/video1':
Duration: N/A, start: 194610.307096, bitrate: N/A
Stream #0:0: Video: h264 (Main), yuv420p(progressive), 320x240, 15 fps, 15 tbr, 1000k tbn, 2000k tbc
Stream mapping:
Stream #0:0 -> #0:0 (h264 (native) -> flv1 (flv))
......
Then read the two files correspondingly:
$ ffmpeg -i raw_input_h264_omx.flv
......
Stream #0:0: Video: h264 (High), yuv420p(progressive), 320x240, 200 kb/s, 15 fps, 15 tbr, 1k tbn
$ ffmpeg -i h264_input.flv
......
Stream #0:0: Video: flv1, yuv420p, 320x240, 200 kb/s, 15 fps, 15 tbr, 1k tbn
It is clear when I give a H.264 stream, ffmpeg firstly decodes it, then pack the raw video into FLV. How to avoid that happen, and have the H.264 stream packed directly?
Supplement: I will eventually pushing multiple video streams, so don't ask me to allow ffmpeg's silent decoding, and encode the stream again.
Unless told otherwise, ffmpeg will transcode streams.
Use
ffmpeg -framerate 15 -s 320x240 -i /dev/video1 -c copy -f flv "rtmp://website/receive/path"
I'm new to this forum, and hope someone can help.
I am trying to add a second audio track (chinese.ac3) to an XVID video (vts_01.avi) that already has an ac3 track.
These audio tracks are encoded to ac3, 48000 Hz, stereo, 128 kb/s, and I would like to keep them that way -- just multiplex the streams without transcoding.
This is the command I am using:
ffmpeg -i vts_01.avi -vcodec copy -i Chinese.ac3 -acodec copy -map 0:0 -map 0:1 -map 1:0 muxed2.avi -newaudio
ffmpeg does its work, except for the fact that it converts the second track to mp2, 64 kb/s.
Here is a relevant excerpt from the output, where the key part is 'Stream #0.2: Audio: mp2, 48000 Hz, stereo, s16, 64 kb/s' where I would like 'Stream #0.2: Audio: ac3, 48000 Hz, stereo, 128 kb/s':
Input #0, avi, from 'vts_01.avi':
Metadata:
encoder : Lavf53.5.0
Duration: 02:03:26.40, start: 0.000000, bitrate: 1954 kb/s
Stream #0.0: Video: mpeg4, yuv420p, 720x352 [PAR 1:1 DAR 45:22], 23.98 tbr,
23.98 tbn, 23.98 tbc
Stream #0.1: Audio: ac3, 48000 Hz, stereo, s16, 128 kb/s
[ac3 # 018A7440] max_analyze_duration 5000000 reached at 5024000
[ac3 # 018A7440] Estimating duration from bitrate, this may be inaccurate
Input #1, ac3, from 'Chinese.ac3':
Duration: 02:03:26.36, start: 0.000000, bitrate: 128 kb/s
Stream #1.0: Audio: ac3, 48000 Hz, stereo, s16, 128 kb/s
File 'muxed2.avi' already exists. Overwrite ? [y/N] y
Output #0, avi, to 'muxed2.avi':
Metadata:
ISFT : Lavf53.5.0
Stream #0.0: Video: mpeg4, yuv420p, 720x352 [PAR 1:1 DAR 45:22], q=2-31, 23.
98 tbn, 23.98 tbc
Stream #0.1: Audio: ac3, 48000 Hz, stereo, 128 kb/s
Stream #0.2: Audio: mp2, 48000 Hz, stereo, s16, 64 kb/s
Stream mapping:
Stream #0.0 -> #0.0
Stream #0.1 -> #0.1
Stream #1.0 -> #0.2
I have tried a number of different combinations, including explicitly forcing the stream to ac3 with:
ffmpeg -i vts_01.avi -vcodec copy -i chinese.ac3 -acodec ac3 -ac 2 -ar 48000 -ab 128k -map 0:0 -map 0:1 -map 1:0 muxed2.avi -newaudio
Same result.
I have also tried to assign a codec to the stream with stream specifier(based on http://ffmpeg.org/ffmpeg.html#toc-Stream-specifiers-1, but these options are not recognized by my ffmpeg.
I am running out of things to try.
(The OP edited the answer into the question. See Question with no answers, but issue solved in the comments (or extended in chat) )
The OP wrote:
I think I just found the solution
from http://ffmpeg-users.933282.n4.nabble.com/Encoding-with-multiple-Audio-tracks-td1289403.html There, James Darley says:
So your command line should look like:
ffmpeg -i INPUT [output options] OUTPUT [audio options] -newaudio [subtitle options] -newsubtitle
I then re-arranged my options accordingly, i.e. audio options for the new track after the output:
ffmpeg -i vts_01.avi -vcodec copy -acodec copy -i Chinese.ac3 muxed3.avi -acodec copy -newaudio
And I now gets my two ac3 audio tracks at the right bitrate.