Newest 'ffmpeg' Questions - Stack Overflow
Les articles publiés sur le site
-
No udp being received on LAN after sending via ffmpeg [closed]
1er mars, par g00seI'm trying to stream a webcam over my LAN with
ffmpeg -s 640x480 -i /dev/video2 \ -framerate 10 \ -preset ultrafast -tune zerolatency codec libx264 \ -f mpegts udp://192.168.1.237:8081
This is all fine when consumed with
ffplay -fflags nobuffer -flags low_delay -framedrop udp://192.168.1.237:8081
on the same box, but when I try to run that same
ffplay
on another box on my LAN, then, nothing. Any ideas please? Also, the following as 'client' simply hangs:nc -u 192.168.1.237 8081 | xxd
-
How can I run FFPROBE in a Python script without triggering the Windows Command window ?
1er mars, par fnord12I am using ffmeg/ffprobe to get video durations (in an addon for Kodi). The code:
result = subprocess.run(["ffprobe", "-hide_banner", "-v", "quiet", "-show_entries", "format=duration", "-of", "default=noprint_wrappers=1:nokey=1", filename], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
The above code and the file importing that code both have a .pyw extension (after first trying regular .py).
This works fine but in Windows 11 it causes the black Windows Command window to briefly flash for each video, despite the -hide_banner flag and loglevel being set to quiet. In Linux Mint it runs without any such window popping up.
Found the answer: subprocess.run just needed a final shell=True as the last argument.
-
Can VLC's method for estimating the duration of a video be reproduced by the means of ffmpeg ?
28 février, par archieThis may seem to duplicate previous questions but it does not, as far as I can tell.
I have a bash script for indexing images and videos to a thumbnails database. A user of my script complained that some videos of hers are skipped over with an error message "corrupted metadata" even though VLC can play them smoothly. These are about 10 videos out of some 15 thousand, but I'd like to solve the problem.
I will focus on a single video from the bunch. File name: "Paper_and_discussion_M492.mkv", actual duration 02:03:47 (hh:mm:ss). The duration and bitrate fields in the video metadata are missing.
ffmpeg -hide_banner -i "Paper_and_discussion_M492.mkv" 2> ffmpeg_data.txt
gives the following output:
Input #0, matroska,webm, from 'Paper_and_discussion_M492.mkv': Metadata: COMPATIBLE_BRANDS: isomiso2avc1mp41 MAJOR_BRAND : isom MINOR_VERSION : 512 ENCODER : Lavf58.76.100 Duration: N/A, start: 0.000000, bitrate: N/A Stream #0:0: Video: hevc (Main), yuv420p(tv, progressive), 854x480 [SAR 1280:1281 DAR 16:9], 24 fps, 24 tbr, 1k tbn, 24 tbc (default) Metadata: HANDLER_NAME : VideoHandler VENDOR_ID : [0][0][0][0] ENCODER : Lavc58.134.100 libx265 Stream #0:1: Audio: vorbis, 44100 Hz, stereo, fltp (default) Metadata: HANDLER_NAME : SoundHandler VENDOR_ID : [0][0][0][0] ENCODER : Lavc58.134.100 libvorbis At least one output file must be specified
Therefore, as expected,
ffprobe -i
-show_entries format=duration -v quiet -of csv="p=0" returns "N/A".
Decoding the whole file does work:
ffprobe -show_entries stream=r_frame_rate,nb_read_frames -select_streams v -count_frames -of compact=p=0:nk=1 -v 0 "Paper_and_discussion_M492.mkv"
but it obviously takes a lot of time, especially for a > 2 hours video.
The "faster answer" proposed by LSerni in https://superuser.com/questions/1179000/ffmpeg-get-duration-of-video-file-without-meta-data should give an estimate of duration based on bitrate; but bitrate is also "N/A" in the incriminated file(s). Their command-line solution based on ffmpeg ends with an error "division by zero".
However, if I open the file with VLC, it plays ok and VLC immediately shows the duration of the file as 02:03:47. I have checked that duration is precise. Search and jump are also very fast: if I skip 1 hr, playback promptly resumes at the right time.
So, a doubt is gnawing at me: How does VLC succeed where I consistently fail? It must have a way for recovering data that I might also be able to use to produce a correct estimate of duration.
My question is: is it possible to reproduce VLC's method (or equivalent) by means of ffmpeg?
-
Bash script to automate FFmpeg operations fails when calling the command, but copy-pasting the generated command into the terminal works [duplicate]
28 février, par GaboScharff99I wrote a bash script which automates a number of conversion operations on video files using FFmpeg. Oddly enough, the FFmpeg call itself now fails when running the script, with a very confusing error message, I might add, but when I copy the command generated by the script into the terminal and run it, it works flawlessly. I'm sorry to insert such a long code block here, but considering how strange this error is, it might be anywhere in the script, so here it is:
#!/bin/bash audioTrack=1 subSource=1 subTrack=0 transcodeVideo=1 transcodeAudio=1 volumeMultiplier=1 degradeToStereo=0 subLanguage="Japanese" while getopts "t:ns:vam:dl:h" opt; do case "$opt" in t) audioTrack=${OPTARG};; n) subSource=0;; s) subTrack=${OPTARG};; v) transcodeVideo=0;; a) transcodeAudio=0;; m) volumeMultiplier=${OPTARG};; d) degradeToStereo=1;; l) subLanguage=${OPTARG};; h) echo "Options:" echo "-t [integer]: Audio track number. Default: 1." echo "-n: If included, subtitles will be taken from internal source." echo "-s [integer]: Subtitles track number. Default: 0." echo "-v: If included, video source will be copied without transcoding." echo "-a: If included, audio source will be copied without transcoding." echo "-m [number]: Volume multiplier. If 1, volume is unaffected. Default: 1" echo "-d: If included, audio will be degraded to stereo." echo "-l [language]: Subtitles language. Only used for external subtitles source. Default: Japanese." exit 0 ;; esac done echo "Audio track: $audioTrack." echo "Subtitles track: $subTrack." params="-map 0:0 -map 0:$audioTrack -map $subSource:$subTrack -c:v" if [[ $transcodeVideo -eq 1 ]]; then echo "Video will be transcoded." params="$params hevc" elif [[ $transcodeVideo -eq 0 ]]; then echo "Video will be copied without transcoding." params="$params copy" fi params="$params -c:a" if [[ $transcodeAudio -eq 1 ]]; then echo "Audio will be transcoded." params="$params libopus" elif [[ $transcodeAudio -eq 0 ]]; then echo "Audio will be copied without transcoding." params="$params copy" fi if [[ $volumeMultiplier -ne 1 ]]; then echo "Volume will be multiplied by a factor of $volumeMultiplier." params="$params -filter:a 'volume=$volumeMultiplier'" else echo "Volume will be unaffected." fi if [[ $degradeToStereo -eq 1 ]]; then echo "Audio will be degraded to stereo." params="$params -ac 2" elif [[ $degradeToStereo -eq 0 ]]; then echo "Audio will not be degraded to stereo." fi params="$params -c:s copy" if [[ $subSource -eq 1 ]]; then echo "Subtitles source is external." echo "Subtitles language is $subLanguage." params="$params -metadata:s:s:0 title='' -metadata:s:s:0 language='$subLanguage'" else echo "Subtitles source is internal." fi if [[ -f titles.txt ]]; then echo "A titles.txt file was found. Titles will be changed according to it." echo "Please check titles.txt to make sure the titles are correct." changeTitles=1 counter=0 else echo "A titles.txt file was not found. Titles will not be changed." changeTitles=0 fi read -p "Are these options correct? (y/n) " choice case "$choice" in y|Y) echo "Initiating conversion sequence. This may take a while..." mkdir output currentParams="" shopt -s nullglob for i in *.mp4 *.mkv; do currentParams=$params fileNameNoExtension=$(echo $i | rev | cut -f 2- -d '.' | rev) if [[ $subSource -eq 1 ]]; then currentParams="-f srt -i $fileNameNoExtension.srt $currentParams" fi if [[ $changeTitles -eq 1 ]]; then ((counter++)) currentParams="$currentParams -metadata title='$(awk "NR==$counter" titles.txt)'" fi ffmpeg -i "$i" $currentParams "output/$fileNameNoExtension.mkv" done echo "Conversion finished!" ;; n|N) echo "Operation canceled. Exiting.";; *) echo "Invalid input. Try again.";; esac
The directory I'm running this in contains six video files:
E1 - The Pirates of Orion.mkv
E2 - Bem.mkv
E3 - The Practical Joker.mkv
E4 - Albatross.mkv
E5 - How Sharper Than a Serpent's Tooth.mkv
E6 - The Counter-Clock Incident.mkv
Here's the
titles.txt
file, for completion's sake:Star Trek: The Animated Series - Season 2, Episode 1 - The Pirates of Orion Star Trek: The Animated Series - Season 2, Episode 2 - Bem Star Trek: The Animated Series - Season 2, Episode 3 - The Practical Joker Star Trek: The Animated Series - Season 2, Episode 4 - Albatross Star Trek: The Animated Series - Season 2, Episode 5 - How Sharper Than a Serpent's Tooth Star Trek: The Animated Series - Season 2, Episode 6 - The Counter-Clock Incident
And finally, here's the error message given by FFmpeg on the terminal for every video file when running the command:
Unable to find a suitable output format for 'Trek:' Trek:: Invalid argument
Maybe there are better ways to handle all of this, but first and foremost, I would like to figure out why the command fails with such a confusing error message. The only place where the string 'Trek:' is found is in the title taken from
titles.txt
, but I don't understand why that's seemingly being passed to the name of the output file instead of the title, and apparently only when running the script.Thanks a lot for your answers! I know this is quite a bit of text, so I really appreciate you taking your time to read through this.
-
How to parallelize ffmpeg setPTS filter when using GPU ? [closed]
28 février, par Souvic ChakrabortyWe have a long python code which chunks the video into multiple parts and changes the speed using setPTS filter.
import ffmpeg ffmpeg.input(segment_path).filter("setpts", f"{1/speed_factor}*PTS").output( adjusted_segment_path,vcodec="h264_nvenc", acodec="aac",preset="fast", crf=23, g=30, keyint_min=30, sc_threshold=0,r=30,vsync='cfr',threads=1 ).global_args("-hwaccel", "cuda").run(quiet=True, overwrite_output=True,capture_stdout=True, capture_stderr=True)
Now, because this happens multiple times before concatenation, we thought, instead of sequential processing using a ThreadPool, it may help reduce the time. So we did that:
import ffmpeg import concurrent.futures def process_video(segment_path, adjusted_segment_path, speed_factor): ffmpeg.input(segment_path).filter("setpts", f"{1/speed_factor}*PTS").output( adjusted_segment_path, vcodec="h264_nvenc", acodec="aac", preset="fast", crf=23, g=30, keyint_min=30, sc_threshold=0, r=30, vsync='cfr', threads=1 ).global_args("-hwaccel", "cuda").run( quiet=True, overwrite_output=True, capture_stdout=True, capture_stderr=True ) segment_paths = ["input1.mp4", "input2.mp4", "input3.mp4"] # List of input video segments output_paths = ["output1.mp4", "output2.mp4", "output3.mp4"] # Corresponding output paths speed_factor = 1.5 # Using ThreadPoolExecutor for concurrent processing with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor: futures = [ executor.submit(process_video, seg, out, speed_factor) for seg, out in zip(segment_paths, output_paths) ] # Wait for all tasks to complete for future in concurrent.futures.as_completed(futures): try: future.result() # This will raise any exceptions encountered in the thread except Exception as e: print(f"Error processing video: {e}")
But the time required did not reduce. Previously, it was 50 seconds for a long video input, now too, it remains the same.
Is there any other way I can improve the code?
I also noticed the GPU utilization is low and the code is still executed sequentially (I can see when I run nvtop, which processes are running)
I am using an L4 GPU with CUDA Version: 12.4, nvcc CUDA Toolkit is also at 12.4