How can I convert WebM file to WebP file with transparency? - ffmpeg

I tried it with ffmpeg.
ffmpeg input.webm output.webp
input.webm contains transparent background and But the alpha channel becomes white in webp. I think that means alpha channel doesn't come together.
I extracted frames with this command:
ffmpeg -i input.xxx -c:v libwebp output_%03d.webp
And it also gives me webp files with white background.
How can I convert it properly with alpha channel? OR should I convert it from other format(extension)?

Use the -c:v libvpx option before the input to change the decoder like in this example for the first frame (-frames:v 1):
ffmpeg -c:v libvpx -i input.webm -frames:v 1 -c:v libwebp -y output.webp
This comment says that:
FFmpeg's native VPx decoders don't decode alpha. You have to use the libvpx decoder
You can check your decoders using ffmpeg -decoders | grep libvpx and you should see an output like this:
V....D libvpx libvpx VP8 (codec vp8)
V....D libvpx-vp9 libvpx VP9 (codec vp9)
According to that output, libvpx would be the decoder for VP8 and libvpx-vp9 for VP9.
You can check the codec of your video using ffprobe input.webm. You should see an output like this:
Stream #0:0(eng): Video: vp8, yuv420p(progressive), 640x360, SAR 1:1 DAR 16:9, 30 fps, 30 tbr, 1k tbn, 1k tbc (default)
Metadata:
alpha_mode : 1
For converting a whole webm (VP8) to an animated webp use:
ffmpeg -c:v libvpx -i input.webm output.webp
For converting a whole webm (VP9) to an animated webp use:
ffmpeg -c:v libvpx-vp9 -i input.webm output.webp

Related

Does Webm support cover art?

I am converting MP3 to Webm and the MP3 file includes a video stream for the cover art.
ffprobe filename.mp3
...
Stream #0:0: Audio: mp3, 22050 Hz, stereo, fltp, 64 kb/s
Stream #0:1: Video: mjpeg (Baseline), yuvj444p(pc, bt470bg/unknown/unknown), 300x300, 90k tbr, 90k tbn, 90k tbc (attached pic)
Using ffmpeg with libopus codec to convert the file causes a VP9 video stream that doesn't work well. I noticed:
VLC Player doesn't show the duration and the progress scrubber doesn't move when playing.
Android Media Player doesn't show image for the cover art of the track.
ffprobe filename.webm
...
Input #0, matroska,webm, from 'webm_bad/B01___01_Matthew_____ENGWEBN2DA.webm':
...
Stream #0:0: Video: vp9 (Profile 1), yuv444p(tv, progressive), 300x300, SAR 1:1 DAR 1:1, 1k tbr, 1k tbn, 1k tbc (default)
If I tried to use -vcodec copy option, then I get this error:
[webm # 0x7fdddf028e00] Only VP8 or VP9 or AV1 video and Vorbis or Opus audio and WebVTT subtitles are supported for WebM.
Could not write header for output file #0 (incorrect codec parameters ?): Invalid argument
Error initializing output stream 0:1 --
Does WebM support cover art? If so, how do I transfer the MP3 cover art over using ffmpeg (or other tool)?
No, WebM does not support cover art.
From the FAQ:
The WebM file structure is based on the Matroska media container.
The cover art in a Matroska container is stored in an attachment:
Attachment Elements can be used to store related cover art, [...]
A WebM container does not support attachments:
Attachment
WebM Support
Element Name
Description
Unsupported
Attachments
Contain attached files.
Unsupported
AttachedFile
An attached file.
Unsupported
FileDescription
A human-friendly name for the attached file.
Unsupported
FileName
Filename of the attached file.
Unsupported
FileMimeType
MIME type of the file.
Unsupported
FileData
The data of the file.
Unsupported
FileUID
Unique ID representing the file, as random as possible.
Unsupported
FileReferral
A binary value that a track/codec can refer to when the attachment is needed.
Unsupported
FileUsedStartTime
DivX font extension
Unsupported
FileUsedEndTime
DivX font extension
Maybe you can consider using a different container. Opus audio streams, like the ones in a WebM container, are supported by other containers:
Opus was originally specified for encapsulation in Ogg containers
If you still want to use WebM, an alternative would be to create a video stream with a still image along with an audio stream. The FFmpeg wiki covers that topic in the Slideshow page. Combining that with this answer, which explains how to extract the cover art of an MP3 file, you could do the following:
ffmpeg -i filename.mp3 -an -c:v copy cover.jpeg
ffmpeg -loop 1 -i cover.jpeg -i filename.mp3 -c:v libvpx-vp9 -c:a libopus -b:a 64k -shortest filename.webm
64k is the bitrate that you show in the output of ffprobe.
The encoding might be slow with the second command. The Encode/Youtube page in the FFmpeg wiki shows an example command to create a video with an still image that uses the -framerate 2 option, like this:
ffmpeg -loop 1 -framerate 2 -i cover.jpeg -i filename.mp3 -c:v libvpx-vp9 -c:a libopus -b:a 64k -shortest filename.webm
For some reason I do not know, the output video of that last command cannot be reproduced by my VLC and the player crashes. 6 was the minimum -framerate that did not crash my player, so be careful.

FFMPEG converting HEVC to VP9 large file size

I'm trying to convert HEVC videos to VP9 so they can be played in a web browser while keeping file size roughly the same.
I am struggling to create a video with similar quality/file size.
Here's the stream info for one of the HEVC videos the video is is 22:49 and 168.7mb:
Stream #0:0(und): Video: hevc (Main) (hev1 / 0x31766568), yuv420p(tv, bt709), 1920x1080, 900 kb/s, 23.98 fps, 23.98 tbr, 90k tbn, 23.98 tbc (default)
The bitrate is 900K so I had thought that the following command would use the same bitrate and give a roughly similar image quality:
ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -vaapi_device /dev/dri/renderD128 -i "$infile" -vf 'format=nv12,hwupload' -c:v vp9_vaapi -b:v 900K -bf 2 -bsf:v vp9_raw_reorder,vp9_superframe -c:a libvorbis "$outfile"
Using this, the quality is noticeably much, much worse and busy scenes look incredibly blocky though the file size is roughly equivalent to the HEVC source.
If I omit the bitrate and let VP9 work it out
ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -vaapi_device /dev/dri/renderD128 -i "$infile" -vf 'format=nv12,hwupload' -c:v vp9_vaapi -b:v 0 -bf 2 -bsf:v vp9_raw_reorder,vp9_superframe -c:a libvorbis "$outfile"
The quality is visually indistinguishable but the file size of the VP9 converted video reaches 401mb, up from 168mb of the HEVC file and during encoding the bitrate is over 3m for most of the video.
I tried going up to 1.2M (33% higher than the source video) and VP9 still gave a very blocky looking video.
Is VP9 really that much worse than HEVC or is there an option I am missing? or is it because I am converting from HEVC?

Using ffmpeg to convert MXF fails

I have an MXF video
I googled syntax to convert to mov and ran it in Mobaxterm on Win10.
"/drives/c/Program Files (x86)/ffmpeg/bin/ffmpeg.exe" -i Clip0001.MXF -c:v libx264 -c:a aac -ab 384k -sn -strict -2 output.mov
I view it in VideoLan and it looks great.
I load it into Magix Movie Studio 15 and audio is fine, but video is green!
ffmpeg output.mov....shows me:
Stream #0:0(eng): Video: h264 (High 4:2:2) (avc1 / 0x31637661), yuv422p, 1920x1080 [SAR 1:1 DAR 16:9], 4530 kb/s, 29.97 fps, 29.97 tbr, 30k tbn, 59.94 tbc (default)
Even this does not work:
ffmpeg.exe -i Clip0001.MXF output.mov
Any suggestions on converting this?
Edit1:
Here is what it looks like in the editor:
Edit2:
Try this and it works, but quality is terrible.
ffmpeg.exe" -i Clip0001.MXF -c:v mpeg4 -c:a aac -ab 384k -sn -strict -2 output.mov
FFmpeg isn't failing; many video editors usually have limited-capability H264 decoders.
Your input has 4:2:2 chroma subsampling and ffmpeg will preserve that when it can. Here, it can and does. However, your video editor can only deal with 4:2:0 subsampled H264 streams.
So, use
ffmpeg.exe -i Clip0001.MXF -pix_fmt yuv420p -c:v libx264 -c:a aac -b:a 384k -sn output.mov
If this command throws an error for the AAC encoder due to the missing -strict -2, your ffmpeg is very old (> 3 years). You should upgrade.

FFMPEG: how to save input camera stream into the file with the SAME codec format?

I have the camera-like device that produces video stream and passes it into my Windows-based machine via USB port.
Using the command:
ffmpeg -y -f vfwcap -i list
I see that (as expected) FFmpeg finds the input stream as stream #0.
Using the command:
ffmpeg -y -f vfwcap -r 25 -i 0 c:\out.mp4
I can successfully save the input stream into the file.
From the log I see:
Stream #0:0: Video: rawvideo (UYVY / 0x59565955), uyvy422, 240x320, 25 tbr, 1k tbn, 25 tbc
No pixel format specified, yuv422p for H.264 encoding chosen.
So, my input format is transcoded to yuv422p.
My question:
How can I cause FFmpeg to save my input video stream into out.mp4 WITHOUT transcoding - actually, to copy input stream to output file as close as possible, with the same format?
How can I cause ffmpeg to save my input videostream into out.mp4 WITHOUT transcoding
You can not. You can stream copy the rawvideo from vfwcap, but the MP4 container format does not support rawvideo. You have several options:
Use a different output container format.
Stream copy to rawvideo then encode.
Use a lossless encoder (and optionally re-encode it after capturing).
Use a different output container format
This meets your requirement of saving your input without re-encoding.
ffmpeg -f vfwcap -i 0 -codec:v copy rawvideo.nut
rawvideo creates huge file sizes.
Stream copy to rawvideo then encode
This is the same as above, but the rawvideo is then encoded to a more common format.
ffmpeg -f vfwcap -i 0 -codec:v copy rawvideo.nut
ffmpeg -i rawvideo.nut -codec:v libx264 -crf 23 -preset medium -pix_fmt yuv420p -movflags +faststart output.mp4
See the FFmpeg and x264 Encoding Guide for more information about -crf, -preset, and additional detailed information on creating H.264 video.
-pix_fmt yuv420p will use a pixel format that is compatible with dumb players like QuickTime. Refer to colorspace and chroma subsampling for more info.
-movflags +faststart relocates the moov atom which allows the video to begin playback before it is completely downloaded by the client. Useful if you are hosting the video and users will view it in their browser.
Use a lossless encoder
Using huffyuv:
ffmpeg -f vfwcap -i 0 -codec:v huffyuv lossless.mkv
Using lossless H.264:
ffmpeg -f vfwcap -i 0 -codec:v libx264 -qp 0 lossless.mp4
Lossless files can be huge, but not as big as rawvideo.
Re-encoding the lossless output is the same as re-encoding the rawvideo.

ffmpeg usage to encode a video to H264 codec format

I have a *.mp4 video file(MPEG4 video codec) and I am trying to convert this to a H264 video codec format(raw h.264 format) using ffmpeg on Linux(Version - FFmpeg version SVN-r0.5.1-4:0.5.1-1ubuntu1, Copyright (c) 2000-2009 Fabrice Bellard,) using command line as shown below,
ffmpeg -i input .mp4 output.h264
but I get an error saying -
Unsupported codec for output stream #0.0
Then when i try this option:
ffmpeg -i input .mp4 -formats h264 output.h264
it still does not work, and gives -
Seems stream 0 codec frame rate differs from container frame rate: 59.94 (5994/100) -> 29.97 (30000/1001)
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'Rapture.mp4':
Duration: 00:02:06.44, start: 0.000000, bitrate: 26574 kb/s
Stream #0.0(eng): Video: h264, yuv420p, 1920x1080, 29.97 tbr, 29.97 tbn, 59.94 tbc
Stream #0.1(eng): Audio: aac, 48000 Hz, stereo, s16
And then it prints out help on the formats which we get when we do ffmpeg -formats
When I checked the help, ffmpeg -formats, I see below information related to H264 file format and codec:
File format :
DE h264 raw H.264 video format
Codecs:
D V D h264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10
My questions :
How can I convert the video to a H264 encoded video (raw H264 video format)
When I do ffmpeg -formats, I see many acronyms for the codecs supported, I see many acronyms before the codec name/type such as - D V D S E A, what do they stand for?
How to use the ffmpeg options -vcodec and -formats?
I used these options to convert to the H.264/AAC .mp4 format for HTML5 playback (I think it may help other guys with this problem in some way):
ffmpeg -i input.flv -vcodec mpeg4 -acodec aac output.mp4
UPDATE
As #LordNeckbeard mentioned, the previous line will produce MPEG-4 Part 2 (back in 2012 that worked somehow, I don't remember/understand why). Use the libx264 encoder to produce the proper video with H.264/AAC. To test the output file you can just drag it to a browser window and it should playback just fine.
ffmpeg -i input.flv -vcodec libx264 -acodec aac output.mp4
I believe you have libx264 installed and configured with ffmpeg to convert video to h264... Then you can try with -vcodec libx264... The -format option is for showing available formats, this is not a conversion option I think...
I believe that by now the above answers are outdated (or at least unclear) so here's my little go at it.
I tried compiling ffmpeg with the option --enable-encoders=libx264 and it will give no error but it won't enable anything (I can't seem to find where I found that suggestion).
Anyways step-by-step, first you must compile libx264 yourself because repository version is outdated:
wget ftp://ftp.videolan.org/pub/x264/snapshots/last_x264.tar.bz2
tar --bzip2 -xvf last_x264.tar.bz2
cd x264-snapshot-XXXXXXXX-XXXX/
./configure
make
sudo make install
And then get and compile ffmpeg with libx264 enabled.
I'm using the latest release which is "Happiness":
wget http://ffmpeg.org/releases/ffmpeg-0.11.2.tar.bz2
tar --bzip2 -xvf ffmpeg-0.11.2.tar.bz2
cd ffmpeg-0.11.2/
./configure --enable-libx264 --enable-gpl
make
sudo install
Now finally you have the libx264 codec to encode, to check it you may run
ffmpeg -codecs | grep h264
and you'll see the options you have were the first D means decoding and the first E means encoding
"C:\Program Files (x86)\ffmpegX86shared\bin\ffmpeg.exe" -y -i "C:\testfile.ts" -an -vcodec libx264 -g 75 -keyint_min 12 -vb 4000k -vprofile high -level 40 -s 1920x1080 -y -threads 0 -r 25 "C:\testfile.h264"
The above worked for me on a Windows machine using a FFmpeg Win32 shared build by Kyle Schwarz. The build was compiled on: Feb 22 2013, at: 01:09:53
Note that -an defines that audio should be skipped.
I have a Centos 5 system that I wasn't able to get this working on. So I built a new Fedora 17 system (actually a VM in VMware), and followed the steps at the ffmpeg site to build the latest and greatest ffmpeg.
I took some shortcuts - I skipped all the yum erase commands, added freshrpms according to their instructions:
wget http://ftp.freshrpms.net/pub/freshrpms/fedora/linux/9/freshrpms-release/freshrpms-release-1.1-1.fc.noarch.rpm
rpm -ivh rpmfusion-free-release-stable.noarch.rpm
Then I loaded the stuff that was already readily available:
yum install lame libogg libtheora libvorbis lame-devel libtheora-devel
Afterwards, I only built the following from scratch: libvpx vo-aacenc-0.1.2 x264 yasm-1.2.0 ffmpeg
Then this command encoded with no problems (the audio was already in AAC, so I didn't recode it):
ffmpeg -i input.mov -c:v libx264 -preset slow -crf 22 -c:a copy output.mp4
The result looks just as good as the original to me, and is about 1/4 of the size!

Resources