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
Related
Currently, I'm working on a python3 script that helps me sort the Google Photos takeout files. The Takeout service for Google Photos actually strips all the metadata of an image/video into a separate JSON file.
This script that I'm working on helps me to merge the timestamp present in the JSON file into its subsequent photo or video. In order to achieve this, I'm currently using - ExifTool by Phil Harvey, which is a Perl executable. I call this tool in a subprocess to edit the Date tags in EXIF/Metadata.
This process is quite hefty and is taking a large amount of time. Then I realised that most of my photos are JPG and videos are MP4, it is very easy to edit Exif data of JPG files in python using some of the libraries present & for the lesser proportion of photos like PNG I can use exiftool.
This has drastically improved the runtime of my script. Now I want to know that is there any way to edit the creation dates of MP4 files natively in python which can theoretically execute faster than the subprocess method.
Please help! Thanks in advance.
Im not too familiar with it, but ffmpeg seems like an option for just the mp4's.
cmd = 'ffmpeg -i "file.mp4" -codec copy -metadata timestamp="new_time_here" "output.mp4"'
subprocess.call(shlex.split(cmd))
modified from:
https://www.reddit.com/r/learnpython/comments/3yotj2/comment/cyfiyb7/?utm_source=share&utm_medium=web2x&context=3
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.
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'm working on a side project where we want to process images in a hadoop mapreduce program (for eventual deployment to Amazon's elastic mapreduce). The input to the process will be a list of all the files, each with a little extra data attached (the lat/long position of the bottom left corner - these are aerial photos)
The actual processing needs to take place in Python code so we can leverage the Python Image Library. All the Python streaming examples I can find use stdin and process text input. Can I send image data to Python through stdin? If so, how?
I wrote a Mapper class in Java that takes the list of files and saves the names, the extra data, and the binary contents to a sequence file. I was thinking maybe I need to write a custom Java mapper that takes in the sequence file and pipes it to Python. Is that the right approach? If so, what should the Java to pipe the images out and the Python to read them in look like?
In case it's not obvious, I'm not terribly familiar with Java OR Python, so it's also possible I'm just biting off way more than I can chew with this as my introduction to both languages...
There are a few possible approaches that I can see:
Use both the extra data and the file contents as input to your python program. The tricky part here will be the encoding. I frankly have no idea how streaming works with raw binary content, and I'm assuming that basic answer is "not well." The main issue is that the stdin/stdout communication between processes is very text-based, relying on delimiting input with tabs and newlines, and things like that. You would need to worry about the encoding of the image data, and probably have some sort of pre-processing step, or a custom InputFormat so that you could represent the image as text.
Use only the extra data and the file location as input to your python program. Then the program can independently read the actual image data from the file. The hiccup here is making sure that the file is available to the python script. Remember this is a distributed environment, so the files would have to be in HDFS or somewhere similar, and I don't know if there are good libraries for reading files from HDFS in python.
Do the java-python interaction yourself. Write a java mapper that uses the Runtime class to start the python process itself. This way you get full control over exactly how the two worlds communicate, but obviously its more code and a bit more involved.
I want to make an editor that does the following:
1) takes an mp3 audio file
2) Takes a picture --a jpg file
3) Outputs a simple video format e.g. .mov which consists of the jpg file with the mp3 file in the background
4) Does NOTHING else
I want to use this as a project to learn just the basics of all this stuff however I do not want to code basic things by hand. Where do I start and what key steps do I take to accomplish this?
I am decent with PHP and Java and do not mind learning Python for this. I actually would ideally want to write this in Python to gain experience.
Thanks!
If you want to code such a solution yourself - forget Python, compile ffmpeg and use it's classes directly from your code after you carefully read them (or maybe use pyffmpeg, which still requires you to know ffmpeg internals).
However, I'm pretty sure that what you want could be done with ffmpeg executable alone from command line - but that way your Python code would end as a wrapper around os.Popen (it's quite popular solution actually).
I think it's a matter of what level of understanding you're aiming at: either you're ok with reading ffmpeg docs and believing it's going to work (then: use Python), or you need to dive deep into ffmpeg sources to gain real understanding what's going on (which I don't have, btw) - and then using pythonic bindings will just stand in your way.
I have needed ffmpeg (from django) a few times already and never had to do anything more than just assemble a list with ffmpeg command line args. On the other hand I would very much like to actually understand what the hell I'm doing, but no one seemed interested in paying me for groking ffmpeg sources. :-(
I'm pretty sure you could do this all from the mencoder commandline (use -speed option I think; might need to give it a duplicate of your jpg for every few seconds of video you want as it can only slow things down by a factor of 100 at the most).
If you opt for the ffmpeg CLI solution, or need a process to try and replicate with the libraries directly, the relevant CLI command would be the straightforward:
ffmpeg -i input.jpg -i input.mp3 output.mov