FFMPEG Drag and Drop sh file - linux

On Windows I have a simple batch file which I drop video files onto to convert to webms, it saves a lot of time as I prefer to just use the same configuration and don't care much about the names.
#echo off
echo.
ffmpeg -i %1 -c:v libvpx-vp9 -quality good -cpu-used 2 -b:v 5000k -qmin 15 -qmax 45 -maxrate 500k -bufsize 1500k -framerate 60 -threads 8 -vf scale=-1:1080 -c:a libvorbis -b:a 192k -f webm %1.webm
pause
I know the .bat file won't really work in Linux (I'm on pop os so pretty much Ubuntu) so with the other lines removed and the %1 changed to $1 it works. It won't do anything if I try dragging and dropping a video file onto it though.
I can type sudo then drag and drop the .sh file followed by a video into a terminal and press enter and it will have the same effect as dragging a video file onto a bat file in Windows.
Is there a way to recreate dragging and dropping a file directly onto another and it executing in Linux or is the terminal the only way?

So ... for me something like this works:
Create a desktop file, e.g. shell.desktop. That needs to look something like this:
[Desktop Entry]
Name=simple
Exec=/bin/bash -c "echo %F; sleep 10" # obviously this is where your ffmpeg incantation goes
Terminal=true
Type=Application
Icon=gvim
Categories=Utility;
StartupNotify=false
That is now a drop target - voila. Mine just echoes back the path of the file dropped.

Related

FFMPEG action on events

iam trying to make action on events in FFMPEG.
For example: ffmpeg -i http://domain/index.m3u8 -c copy -f segment -strftime 1 -segment_time 10 %Y-%m-%d-%H-%M-%S.mp4
FFMPEG take live stream, cut by slices and create files. I want to run a script do_with_file.sh after every slice created, without ffmpeg pausing.
Is there any option in ffmpeg to make it?
Ofcource, i can take stdout from ffmpeg and looking for "segment" text:
ffmpeg ....mp4 | grep 'segment #' | do_with_file.sh
First of all, info line about "segment" showed in stdout, before file was created.
It is not working, if i want run ffmpeg in background.
And in my mind, it is not geek way :)
P.S. English is not my native language, sorry for mistakes.
You can ask ffmpeg to tell you when a segment is finished recording:
-loglevel verbose
With this option you'll get the event you're looking for:
[segment # 0x0f0f0f0f0f0f] segment:'filename.ext' count:N ended
But, if you're prefer a "geek" way, you may try inotifywait:
while segment=$(inotifywait --quiet --event close_write --format %w%f path/to/dir); do
do_with_file $segment
done

Combine images into video (with audio in background) in ffmpeg

I have a folder with 15 images and 1 audio file:
image_1.jpg, image_2.jpg, image_3.jpg ..... and music.webm
(Also resolution of images is 1440x720)
I want to combine these images into a video with audio in background.And framerate I require is 0.2 (5 second for each frame).I gave a search on Stackoverflow and I found the nearest example and tried.But it failed.
ffmpeg -f image2 -i image%03d.jpg -i music.webm output.mp4
(Actually I have very little knowledge of ffmpeg so please excuse my foolishness)
Please help me with my issue.(Also I didn't understood where in the code I have to enter framerate)
Edit:-If needed I can easily tweak with filename of images.Be free to tell me that too
How your command failed? please paste the text.
According to your image file format, the pattern should be: %3d, but not %03d
e.g.
image_%d.jpg apply to: image_1.jpg, image_2.jpg, image_3.jpg
image_%04d.jpg apply to: image_0001.jpg, image_0002.jpg ... image9999.jpg
and also , when using this "pattern sequence", MAKE SURE:
the sequence should start from xxx001.jpg, otherwise you should specify a parameter -start_index or something.
the sequence must not broken. e.g. image5.jpg, image6.jpg, (missing 7 ) image8.jpg
refer:
https://ffmpeg.org/ffmpeg-formats.html#image2-2
https://en.wikibooks.org/wiki/FFMPEG_An_Intermediate_Guide/image_sequence
Try this:
ffmpeg -r 0.2 -i image_%02d.jpg -i music.webm -vcodec libx264 -crf 25 -preset veryslow -acodec copy video.mkv
So -r specifies fps (I actually didn't try using a float value there, but try it)
-vcodec specifies video codec, -crf quality, preset the encoding speed (slower is more efficient), -acodec copy says audio should be copied.
I think that should work, give it a try. You will need to rename the images to image_01.jpg image_02...
Also have a look here: How to create a video from images with FFmpeg?

How to find if the videos have sound in it?

I've a some hundreds of video files in a folder structure. All of them have video and audio streams, but some of them don't have any sound, despite having an audio stream. Is there a way to find out those files without having to resort to opening each file individually.
Most ways I know only check if there is an audio stream.
Thanks.
You can run the following in batch mode:
ffmpeg -hide_banner -i file.mp4 -af volumedetect -vn -f null - 2>&1 | grep mean_volume
The output for each file will be of the form
[Parsed_volumedetect_0 # 0000000002b1e800] mean_volume: -17.2 dB
Perfect digital silence will have a value of -91 dB, but anything below, say, -40 dB is probably just tape noise. Test and verify a few inputs manually and set a value.

Set up basic Batch or Node.JS prompts for FFMPEG?

I have some game clips from Nvidia shadow play that I like to casually shorten and / or turn them into webms or keep them as mp4s. I use the same ffmpeg line for them. I do slightly change the line because of the input file, start time, and output file.
How could I set up something like a batch file (I was thinking maybe node as well) where it just asks for the input file, start time, and output file?
The current ffmpeg command line I use is like this:
ffmpeg -i desktop.mp4 -ss 00:01:50 -b 900000 -vf scale=640:trunc(ow/a/2)*2 output.webm
You can prompt for user input using the following pattern:
SET /P FILENAME=Enter Filename:
ECHO USER ENTERED %FILENAME%
So with your code you'd setup your 3 variables then use:
ffmpeg -i "%INFILE%" -ss %STARTTIME% -b 900000 -vf scale=640:trunc(ow/a/2)*2 "%OUTFILE%"

Passing processed Video from OpenCV to FFmpeg for HLS streaming (Raspberry PI)

Hi I a have a question I have openCV and ffmpeg on the Raspberry Pi and I am trying to stream live video from the raspberry pi. At the moment I have the output output of openCV saving as a .avi file and I have a command for ffmpeg
ffmpeg -i out.avi -hls_segment_filename '%03d.ts' stream.m3u8
This Command take the output creates the playlist(.m3u8) and the segments(.ts).
At present I have openCV programmed in C++ (this can not change) I have an executable programmed from this and I have both the executable C++ and the above ffmpeg in a Bash Script.
#!/bin/bash
while true; do
./OpenCV
ffmpeg -i out.avi -hls_segment_filename '%03d.ts' stream.m3u8
done
This does allow me to stream the processed openCV video my issue is as the Bash script is in a while loop it keeps resetting the playlist and the .ts files, so i have to constantly press play on the client connection.
Is there anyway around this?
I tried including a variable that would increment every loop but if i replace '%03d' with this i get an error.
If you insist on using your program (OpenCV) and ffmpeg in a loop then you can specify the initial hls sequence number for stream.m3u8 using start_number. Something like this:
... as before ...
ffmpeg -i out.avi -hls_segment_filename '%03d.ts' --start_number $I stream.m3u8
where I is a variable that you have to increment each time the loop runs.
But this approach is very fragile and will probably result in an incorrect stream because it assumes that ffmpeg will produce only a single segment but in reality it will probably produce multiple segments.
A much better approach is to run OpenCV and ffmpeg in parallel and make them talk to each other. By doing so there will be no need to write to a temporary file out.avi and run OpenCV and ffmpeg in sequences and keep the media sequences synchronized.
I think you can hack it like this. Note that you may need to change OpenCV so that it writes constantly to out.avi and does not return after a while:
./OpenCV &
tail -n +0 -f out.avi | ffmpeg -i pipe:0 -hls_segment_filename '%03d.ts' stream.m3u8
A better approach is change your program to write to stdout or to a named pipe and run it like so:
./OpenCV | ffmpeg -i pipe:0 -hls_segment_filename '%03d.ts' stream.m3u8

Resources