ffmpeg - how to copy exactly the video settings except for the resolution - ffmpeg

I want to change the resolution of my .flv file. I have tried "ffmpeg -i file.flv -s 1280x720 -acodec copy file2.flv", but the output file has different video encoding settings. I have added "-vcodec libx264" which makes the output settings closer to the input settings, but there are still little differences such as fps. I realize that I could probably use mediainfo and figure out how to format that information in a way ffmpeg can use, but that seems like a very clunky solution. Is there a way for ffmpeg to copy the encoding settings from the input and apply them to the output with a resolution change?

Related

ffmpeg Produces unplayable MP4 File From avi files

A have a hand full of .avi files which I would like to convert to .mp4. Cobbling together everything I have found on the Internet, I end up with something like this:
ffmpeg -i something.avi -c:v copy -c:a copy something.mp4
What I get is playable on VLC player, but, of course, that will play anything I through at it. However, I cannot play it using QuickLook in the Finder or with the QuickTime player.
In some cases I get video, but no sound. In some other cases I get garbled video.
I am guessing that the audio or video codec inside the .avi file is incompatible with MacOS, and that the copy instruction above is not appropriate. In that case I guess that I would actually need to reencode the audio or video.
If this sounds incoherent, I admit I know very little about video files.
What would be the best settings to try to produce an MP4 which works natively on MacOS?
"What would be the best settings to try to produce an MP4 which works natively on MacOS?"
Check this useful guide.
You can try the below command as a starting point (audio track will / should be auto-detected & converted):
ffmpeg -i something.avi -c:v libx264 -crf 22 -pix_fmt yuv420p something.mp4

ffmpeg: crop video into two grayscale sub-videos; guarantee monotonical frames; and get timestamps

The need
Hello, I need to extract two regions of a .h264 video file via the crop filter into two files. The output videos need to be monochrome and extension .mp4. The encoding (or format?) should guarantee that video frames are organized monotonically. Finally, I need to get the timestamps for both files (which I'd bet are the same timestamps that I would get from the input file, see below).
In the end I will be happy to do everything in one command via an elegant one liner (via a complex filter I guess), but I start doing it in multiple steps to break it down in simpler problems.
In this path I get into many difficulties and despite having searched in many places I don't seem to find solutions that work. Unfortunately I'm no expert of ffmpeg or video conversion, so the more I search, the more details I discover, the less I solve problems.
Below you find some of my attempts to work with the following options:
-filter:v "crop=400:ih:260:0,format=gray" to do the crop and the monochrome conversion
-vf showinfo possibly combined with -vsync 0 or -copyts to get the timestamps via stderr redirection &> filename
-c:v mjpeg to force monotony of frames (are there other ways?)
1. cropping each region and obtaining monochrome videos
$ ffmpeg -y -hide_banner -i inVideo.h264 -filter:v "crop=400:ih:260:0,format=gray" outL.mp4
$ ffmpeg -y -hide_banner -i inVideo.h264 -filter:v "crop=400:ih:1280:0,format=gray" outR.mp4
The issue here is that in the output files the frames are not organized monotonically (I don't understand why; how come would that make sense in any video format? I can't say if that comes from the input file).
EDIT. Maybe it is not frames, but packets, as returned by av .demux() method that are not monotonic (see below "instructions to reproduce...")
I have got the advice to do a ffmpeg -i outL.mp4 outL.mjpeg after, but this produces two videos that look very pixellated (at least playing them with ffplay) despite being surprisingly 4x bigger than the input. Needless to say, I need both monotonic frames and lossless conversion.
EDIT. I acknowledge the advice to specify -q:v 1; this fixes the pixellation effect but produces a file even bigger, ~12x in size. Is it necessary? (see below "instructions to reproduce...")
2. getting the timestamps
I found this piece of advice, but I don't want to generate hundreds of image files, so I tried the following:
$ ffmpeg -y -hide_banner -i outL.mp4 -vf showinfo -vsync 0 &>tsL.txt
$ ffmpeg -y -hide_banner -i outR.mp4 -vf showinfo -vsync 0 &>tsR.txt
The issue here is that I don't get any output because ffmpeg claims it needs an output file.
The need to produce an output file, and the doubt that the timestamps could be lost in the previous conversions, leads me back to making a first attempt of a one liner, where I am testing also the -copyts option, and the forcing the encoding with -c:v mjpeg option as per the advice mentioned above (don't know if in the right position though)
ffmpeg -y -hide_banner -i testTex2.h264 -copyts -filter:v "crop=400:ih:1280:0,format=gray" -vf showinfo -c:v mjpeg eyeL.mp4 &>tsL.txt
This does not work because surprisingly the output .mp4 I get is the same as the input. If instead I put the -vf showinfo option just before the stderr redirection, I get no redirected output
ffmpeg -y -hide_banner -i testTex2.h264 -copyts -filter:v "crop=400:ih:260:0,format=gray" -c:v mjpeg outR.mp4 -vf showinfo dummy.mp4 &>tsR.txt
In this case I get the desired timestamps output (too much: I will need some solution to grab only the pts and pts_time data out of it) but I have to produce a big dummy file. The worst thing is anyway, that the mjpeg encoding produces a low resolution very pixellated video again
I admit that the logic how to place the options and the output files on the command line is obscure to me. Possible combinations are many, and the more options I try the more complicated it gets, and I am not getting much closer to the solution.
3. [EDIT] instructions how to reproduce this
get a .h264 video
turn it into .mp by ffmpeg command $ ffmpeg -i inVideo.h264 out.mp4
run the following python cell in a jupyter-notebook
see that the packets timestamps have diffs greater and less than zero
%matplotlib inline
import av
import numpy as np
import matplotlib.pyplot as mpl
fname, ext="outL.direct", "mp4"
cont=av.open(f"{fname}.{ext}")
pk_pts=np.array([p.pts for p in cont.demux(video=0) if p.pts is not None])
cont=av.open(f"{fname}.{ext}")
fm_pts=np.array([f.pts for f in cont.decode(video=0) if f.pts is not None])
print(pk_pts.shape,fm_pts.shape)
mpl.subplot(211)
mpl.plot(np.diff(pk_pts))
mpl.subplot(212)
mpl.plot(np.diff(fm_pts))
finally create also the mjpeg encoded files in various ways, and check packets monotony with the same script (see also file size)
$ ffmpeg -i inVideo.h264 out.mjpeg
$ ffmpeg -i inVideo.h264 -c:v mjpeg out.c_mjpeg.mp4
$ ffmpeg -i inVideo.h264 -c:v mjpeg -q:v 1 out.c_mjpeg_q1.mp4
Finally, the question
What is a working way / the right way to do it?
Any hints, even about single steps and how to rightly combine them will be appreciated. Also, I am not limited tio the command line, and I would be able to try some more programmatic solution in python (jupyter notebook) instead of the command line if someone points me in that direction.

Using ffmpeg to convert an SEC file

I need to convert an SEC file into any video format that I can share and/or upload to Youtube. MP4, etc.
I'm a complete newbie at all things terminal. I've tried:
ffmpeg -i video.sec video.mp4
ffmpeg -i video.sec -bsf:v h264_mp4toannexb -c:v copy video.avi
ffmpeg -i video.sec -b 256k -vcodec h264 -acodec aac video.mp4
I don't understand what any of these mean, they're just examples I found online. However, whatever I try returns this error:
Invalid data found when processing input
Any thoughts? Thanks!
I had to add the following option so it would skip the SEC's custom header.
-skip_initial_bytes 48
i know this is old, but i was trying to figure this out as well, what ended up finally working for me was this command.
./ffmpeg -f h264 -i INPUT.sec -filter:v "setpts=4*PTS" OUTPUT.avi
the -f h264 was the part i was missing. and the -filter:v "setpts=4*PTS" part is to slow it back down to the original speed. you can also change the .avi at the end to whichever format works best for you.
i hope this helps someone out :)
OK, just to clear up some recent threads…
The Samsung DVR used here was an SRD-440. RB kindly sent me a file to test and he sent me a .BU file with an associated .db2 file. This was a bit of a surprise as in all older Samsung DVR’s, the .bu files can only be played back in the DVR. I mentioned this here, https://spreadys.wordpress.com/2014/07/21/ifsec-samsung-exports/
It appears that Samsung have caught on, and the BU file is now playable due to it being a H264/AVC Stream conforming to a standard profile. I have updated the IFSEC Post mentioned above to highlight this change.
Back to RB’s stream and the challenge was to get these files viewable in WMV format. They were all field based, at 704×288.
The speed of playback is controlled by the Samsung software, using the .db2 file. As such, the metadata and timing information in the video stream was wrong. This caused speed issues and then quality issues when attempting to correct this.
As a result, I found it necessary to force an input rate and generate a new Presentation Time Stamp BEFORE the input file.
The following FFmpeg string did the job…
ffmpeg -r 12 -fflags genpts -i FILE.bu -vf scale=704:528 -sws_flags lanczos -q:v 2 FILE.wmv
Remember, this is for preview – analysis would be completed differently due to the scaling, the interpolation method, and the WMV compression!
As its likely that RB may have quite a few .bu files in a folder, I placed this into a batch file to transcode the whole lot within a few minutes… more on batch files coming in a new post soon!
https://spreadys.wordpress.com/2014/07/21/ifsec-samsung-exports/
or
ffmpeg -i (name of file).sec (name of final file).mp4
ffmpeg -i (name of file).sec -filter:v "setpts=3.3*PTS" (name of final_file).mp4

Is this transcoding the video?

I have an application used in government and subject to regulation that prevents transcoding or altering the video quality in any way.
I’m attempting to utilize FFmpeg to change a video into an MP4 by copying the raw streams to a new container.
This is the command being used:
ffmpeg.exe -y -i INPUT.ASF -c:av copy OUTPUT.MP4
Notice the -c:av copy. The FFmpeg documentation says, “a special value copy (output only) to indicate that the stream is not to be re-encoded.“
Visually the videos before and after appear to be identical quality with no pixelation on the ships.
Is this altering the video quality or could this be considered transcoding?
There's a syntax error but other than that, yes, copy will avoid transcoding of the stream. The hitch is that the output container may not support all codecs that the input container does.
ffmpeg.exe -y -i INPUT.ASF -c copy OUTPUT.MP4
Your current command was transcoding the video since ffmpeg's parser only consumes the first character in stream type i.e. -c:av is treated as -c:a. -c copy will copy all stream types. Use -c:v copy -c:a copy to separately set codec mode for video and audio.

ffmpeg -r option

I am trying to use ffmpeg (under linux) to add a small title to a video. So, I use:
ffmpeg -i hk.avi -r 30000/1001 -metadata title="SOF" hk_titled.avi
The addition of title seems to work, but, the problem is the output file is about a 1/3rd of the file size of the input file and I was wondering why this is? Is this at the expense of quality of the video? I am unsure.. How do I preserve the same quality/size as the input file?
The main point I am unable to figure out is the use of -r option. Going through the ffmpeg docs, it seems to suggest that -r is frames per second (The input video is 23.9fps). At the moment, (30000/1001) works out to 29 fps, but I was unsure if I should be using this value.
Thanks for your time.
The default settings for ffmpeg do not always provide a good quality output when you encode, but this depends on your output format and the available encoders. With your output ffmpeg will use the default of -b 200k or -b:v 200k.
However, you can tell ffmpeg to simply copy the input streams without re-encoding and this is recommended if you just want to add or edit metadata. These examples do the same thing but use different syntax depending on your ffmpeg version:
ffmpeg -i hk.avi -vcodec copy -acodec copy -metadata title="SOF" hk_titled.avi
ffmpeg -i hk.avi -c copy -metadata title="SOF" hk_titled.avi

Resources