Yes I know that this has been asked many many times, but the libraries on every single answer just ends up needing ffmepg.
The problem with that is that the file size increases dramatically when I include ffmpeg to my project, and I just don't want that.
I want to keep my project as lightweight as possible without needing to add 200 meabytes of data just for video to audio conversion which is just a very small part of the project.
So is there any way to
not use ffmpeg
use another lightweight converter with a python wrapper
just use the parts in ffmpeg where the webm to mp3 conversion is actually taking place
Compile your own ffmpeg using this configuration to decode Vorbis/Opus audio in WebM and encode MP3 via libmp3lame:
./configure --disable-everything --disable-network --disable-autodetect --enable-small --enable-protocol=file,pipe --enable-demuxer=matroska --enable-muxer=mp3 --enable-decoder=vorbis,opus --enable-encoder=libmp3lame --enable-libmp3lame --enable-filter=aresample
Resulting size of ffmpeg is under 2 MB.
Related
I have a bunch of videos for which I want to extract specific sections (either as videos or as frames). I get the specific sections from a .json file where the start and end frames are stored according to labels, like 'cat in video', 'dog in video'. I have an existing method in Python using opencv using the method mentioned here but I found a one-liner using ffmpeg which is a lot more faster and efficient than my Python script, except that I have to manually fill in the start and end frames in this command.
ffmpeg -i in.mp4 -vf select='between(n\,x\,y)' -vsync 0 frames%d.png
I read a few questions about working with .json files in a shell script or passing arguments to a batch script which looks quite complicated and might spoil my system. Since I'm not familar working with .json files in a shell/batch script, I'm not sure how to start. Can anyone point me in the right direction on how to make a batch script that can read variables from a .json file and input it into my ffmpeg command?
Since you're already familiar with Python, I suggest you to use it to parse JSON files, then you can use ffmpeg-python library, which is a ffmpeg binding for Python. It also has a crop function, which I assume is what you need.
An alternative would be to use the os.system('ffmpeg <arguments>') calls from a Python script, which allows you to run external tools from the script.
Python natively supports JSON with its builtin json package
As for doing this in python, here is an alternative approach that you can try my ffmpegio-core package:
import ffmpegio
ffmpegio.transcode('in.mp4','frames%d.png',vf=f"select='between(n\,{x}\,{y})'",vsync=0)
If the videos are constant frame rate, it could be faster to specify the start and end timestamps as input options:
fs = ffmpegio.probe.video_streams_basic('in.mp4')[0]['frame_rate']
ffmpegio.transcode('in.mp4', 'frames%d.png', ss_in=x/fs, to_in=y/fs, vsync=0)
If you don't know the frame rate, you are calling ffprobe and ffmpeg for each file, so there is a tradeoff. But if your input video is long, it could be worthwhile.
But if speed is your primary goal, calling FFmpeg directly always is the fastest.
ffmpegio GitHub repo
I'm using OpenCV with Python, but actually can switch to C++, so if it's matter please answer question considering it.
I'm writing .avi file(joining multiple avi files into one) using
cv2.VideoWriter([filename, fourcc, fps, frameSize[, isColor]])
but recently found out that I can't write .avi file larger than 2 GB with it. It even mentioned there: Due to this OpenCV for video containers supports only the avi extension, its first version. A direct limitation of this is that you cannot save a video file larger than 2 GB.
But right now I've got no time to learn new library like ffmpeg, I need to do it very fast.
How can I write this file, using C++ or Python with knowledge of OpenCV, or at least with input part - using
cv::Mat
as frames
This limitation was removed in OpenCV 3.0, due to the introduction of new file formats such as .mkv, who do support video files larger than 2GB.
See Does OpenCV 3.0 Still Has Limits On VideoWriter Size?.
NOTE: The documentation and examples weren't updated yet, so maybe this should be considered experimental.
You have answered your own question but I'm afriad it isn't the answer you want.
From your link
As you can see things can get really complicated with videos. However, OpenCV is mainly a computer vision library, not a video stream, codec and write one. Therefore, the developers tried to keep this part as simple as possible. Due to this OpenCV for video containers supports only the avi extension, its first version. A direct limitation of this is that you cannot save a video file larger than 2 GB. Furthermore you can only create and expand a single video track inside the container. No audio or other track editing support here. Nevertheless, any video codec present on your system might work. If you encounter some of these limitations you will need to look into more specialized video writing libraries such as FFMpeg or codecs as HuffYUV, CorePNG and LCL.
What this paragraph says is that the developers of OpenCV made a design choice that says you cannot write video files larger than 2Gb using OpenCV for the specific reason that it is a computer vision library not a video tool.
Unfortunately if you want to write videos larger than 2Gb you are going to need to learn to use FFMPEG or something similar (It isn't that hard and has good bindings to OpenCV)
I am writing a little python script that converts mp3 files to aac. I am doing so by using avconv and I am wondering if I am doing it right.
Currently my command looks like this:
avconv -i input.mp3 -ab 80k output.aac
This brings me to my first question: I am using -ab 80k as this works with my test-files. On some files I can go higher and use 100k. But I'd prefer to have that always on the highest settings. Is there a way to say that?
The other question: I am using it in a python script. Currently I call it as a subprocess. What I'd prefer is not to do so, as this forces me to write a file to disc and then load it again when everything is done. Is there a way to only do it in memory? I am returning the file afterwards using web.py and don't need or want it on my disc? So would be cool not having to use temporary files at all.
Thanks for any tipps and tricks :)
I don't have the -ab option but if it is equivalent to -ar (specify the sample rate), I should point out that your ears won't be able to tell the difference between 80k and anything higher.
On the subject of temporary files, have you considered using /tmp or a specific tmpfs file system created for the purpose.
Edit:
In response to comment about tempfiles, yes you still use them but create them in /tmp or a tmpfs file system that you have created for the job. It should get cleared on reboot but I would expect you to delete the file once you have passed it on anyway.
The other point about lossless aac I may come back to you later.
Edit 2:
As I suspected the aac format is described as the logical successor to mp3 and I strongly suspect, you or someone else may know different, that as mp3 is what is termed as lossy, compressed i.e. bits ( no pun intended) missing, your desire to convert losslessly is doomed, in so much as the source is already lossy.
Of course, being no expert in the matter, I stand to be corrected.
Edit 3:
your comment about too many frames leads me to believe that you are conflating the two avconv options -ar and -b
The -b is used for video and specifies the output bit rate for video and audio. The way you are using it, I suspect that it is attempting to apply the same bit rate to audio and video but there is a limit on the audio stream.
You would have to use -b:v to tell avconv to set the video bit rate and leave the audio rate alone.
I suggest that you lose the -ab option and use -ar instead as that is audio only.
I want to write a python program that could extract audio from a video file (e.g. video.avi).
Is there any good library for it? And where should I start from?
I tried to use PyMedia, but I couldn't install it on my MacOSX(Mountain Lion).
EDIT:
The problem is video.avi is not completely available. Someone is writing on it and adding some frames to it every second. So I wanted to write a code in python to get the video as it comes and extract the audio from it and write it to a file (e.g. audio.mp3, audio.wav).
I don't know if ffmpeg can wait for the video to be copied to video.avi.
And I cannot wait for the video to be copied completely and then do the audio extraction. I have to do it as it comes.
I don't have a complete solution, but from the ffmpeg docs, it looks like ffmpeg can read an incomplete file by piping to stdin. Example from the docs:
cat test.wav | ffmpeg -i pipe:0
If you must use python, you can always call ffmpeg using subprocess.
I am trying to use the Opencv VideoWriter object with the mpeg-1 encoding to create videos, I am aiming at writing only two images on that video, using mpeg-1 encoding, I would like to know how much the first image that I wrote first helps in compressing the second image. In other words find the file size before writing the 2nd image and after. My questions are:
Is there any way to perform this process using Opencv?
Is there a way to avoid writing on disks and just have the information of the size of the compreesed video( after adding the second image)?
Is there any other good alternatives reach my goals?
I suggest you learn GStreamer framework which has Python bindings available.
http://gstreamer.freedesktop.org/modules/gst-python.html
It works best on Linux platforms, some OSX support is available.
GStreamer provides "sane", but very powerful and very complex, APIs for procedural video and audio generation.
See also:
GStreamer: status of Python bindings and encoding video with mixed audio
Alternative you can write out frames to raw image images files and parse them to a video using ffmpeg command. Might work on Microsoft Windows platforms too.