0

I think I'm pretty close to having a code which will start at a directory, then spit out a fixed copy, using fd (instead of find) and ffmpeg. I have written the if statement here as psudo-code:

for i in $(fd -e .mp4 -e .avi); 
do if [ffmpeg -v error -i "$i" -f null - 2] has an error, then
ffmpeg -err_detect ignore_err -i video.mkv -c copy video_fixed.mkv;
done

I believe that when you use 'fatal' if there is no fatal error, the file will be blank/zero. Which would be easier, but I think 'error' is more appropriate.

What I want to modify is to have the IF statement execute if there are errors, and do nothing if not. If there are errors it will create the video_fixed.mkv. However, I also don't want this to be video_fixed.mkv, I want it to be the same file name as $i with the same file extension as the original, and to replace the original with it. I'm also not sure if $i is just the filename, or the filename including the entire path, which makes things tricky, I'd have to capture the string after the last '/' as the file name.

If it's too hard to do the comparison, I'll have to just copy all the files regardless of if they have errors, but to do this I'll still need to name and override the copies to be the same as the originals.

Thanks

4
  • It's not clear what you mean with "if you use 'fatal'": That's not a "shell" or "Unix" term I'm aware of, it also means nothing specific to ffmpeg, as far as I know! Why make things abstract with pseudocode if you could also post actual code that is unambiguos in what you mean. Commented Aug 9, 2023 at 12:59
  • Hi. 'fatal' is part of ffmpeg, it is - loglevel16, whereas 'error' is level 8. Hard for me to write the actual IF code, but I'll try: for i in $(fd -e .mp4 -e .avi); do if [-n $(ffmpeg -v error -i "$i" -f null - 2)] then $(ffmpeg -err_detect ignore_err -i video.mkv -c copy video_fixed.mkv) fi; done
    – 1toneboy
    Commented Aug 9, 2023 at 20:57
  • Ahhhh! I was missing the loglevel there! Commented Aug 10, 2023 at 7:32
  • I haven't tried the IF statement. Run the following commands from the folder with the video files in it- Create duplicate folder called correctedVideos to save everything in: IFS=$'\n'; find . -type d | xargs -I {} mkdir -p /home/Rob/Desktop/correctedVideos/{}; for i in $(fd -e .mp4 -e .avi); do ffmpeg -err_detect ignore_err -i "$i" -c copy "/home/Rob/Desktop/correctedVideos/$i"; done OR- Create files in same folder but prefixed with copied_: IFS=$'\n'; for i in $(fd -e .mp4 -e .avi); do ffmpeg -err_detect ignore_err -i "$i" -c copy "/home/Rob/Desktop/${i%/*}/copied_${i##*/}"; done
    – 1toneboy
    Commented Aug 14, 2023 at 9:16

1 Answer 1

0

I haven't tried the IF statement, however I've made enough progress.

Run the following commands from the folder with the video files in it-

Create duplicate folder called correctedVideos to save everything in:

IFS=$'\n'; find . -type d | xargs -I {} mkdir -p /home/Rob/Desktop/correctedVideos/{}; for i in $(fd -e .mp4 -e .avi); do ffmpeg -err_detect ignore_err -i "$i" -c copy "/home/Rob/Desktop/correctedVideos/$i"; done

Where i is a variable, like from a for loop or input, could be anything not necessarily i-

Will show just file name: ${i##*/}

Will show just the file path down from current directory: ${i%/*}

Will show relative file path from current directory and file name: "$i"

so "$i" is the same as ${i%/}/${i##/}

You need to use absolute paths, in full not '~'

P.S. If you don't want to create a parallel folder with copies in it and instead want to create copies in the existing folder there are two methods-

Method 1: For each file in a single folder (issues if there are sub-folders, so don't use in a folder with subfolders):

IFS=$'\n'; for i in $(fd -e .mp4 -e .avi); do echo ffmpeg -err_detect ignore_err -i "$i" -c copy "copied_$i"; done

Method 2: For a folder with subfolders, but doesn't work if there are any files in the toplevel folder where the command is run from:

IFS=$'\n'; for i in $(fd -e .mp4 -e .avi); do ffmpeg -err_detect ignore_err -i "$i" -c copy "$PWD/${i%/*}/copied_${i##*/}"; done

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .