LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Extract JPGs from Nested Directory of MP4s, Leaving Each JPG in its Source MP4 Directory (https://www.linuxquestions.org/questions/linux-newbie-8/extract-jpgs-from-nested-directory-of-mp4s-leaving-each-jpg-in-its-source-mp4-directory-4175631578/)

ericlindellnyc 06-09-2018 09:05 AM

Extract JPGs from Nested Directory of MP4s, Leaving Each JPG in its Source MP4 Directory
 
I have this script, which creates a directory for each file, & moves the file into the directory.

Code:

#!/bin/bash
for file in *; do
  if [[ -f "$file" ]]; then
    mkdir "${file%.*}"
    mv "$file" "${file%.*}"
  fi
done

Code:

Now, I need to 'visit' each file (all MP4s) inside its directory,
    then create a JPG from each frame with ffmpeg,
    leaving JPGs inside that directory.

I create JPGs from MP4's with ..
Code:

ffmpeg -i putin.mp4 -y -f image2 -c:v mjpeg %03d.jpg
[using video "putin.mp4"]

I don't know how to ensure the extracted JPGs appear inside their associated MP4's directory. If I apply the ffmpeg extraction in the foregoing, JPGs will go in a higher-level directory, I think.

hydrurga 06-09-2018 09:19 AM

I'm not an expert at Bash (which may illustrate itself with my answer), but can you not just cd into each directory before issuing the ffmpeg command?

Or, as you are probably looping through the directories with a variable anyway, use that variable to provide a path for ffmpeg's -i option and the final .jpg option (if the latter is allowed)?

AwesomeMachine 06-09-2018 10:31 AM

You can use a command substitution with 'pwd', like
Code:

ffmpeg -i file $(pwd)/output_file

michaelk 06-09-2018 10:46 AM

To elaborate on the other posts but untested.

Code:

  if [[ -f "$file" ]]; then
    newdir="${file%.*}"
    mkdir "$newdir"
    mv "$file" "$newdir"
    ffmpeg -i "$newdir"/"$file" -y -f image2 -c:v mjpeg "$newdir"/%03d.jpg
  fi


scasey 06-09-2018 10:51 AM

Quote:

Originally Posted by AwesomeMachine (Post 5865451)
You can use a command substitution with 'pwd', like
Code:

ffmpeg -i file $(pwd)/output_file

While that's true, how is
Code:

$(pwd)
different from
Code:

./
?
Doesn't pwd always return the name of the current directory?

BW-userx 06-09-2018 11:39 AM

Code:

#!/bin/bash
for file in *; do
  if [[ -f "$file" ]]; then
    mkdir "${file%.*}"
    mv "$file" "${file%.*}"
  fi
done

that is set up to run and create a new sub-dir within that parent dir. If when running this and it does not complete in time, say you got a lot to do and x amount of time to do them, and you do not complete the task, then you go back to finish it, what effects are you going to experience?
Code:

#!/bin/bash
working_dir=
move_to=
script_dir=
for file in "$working_dir"/* ;
do
  if [[ -f "$file" ]]; then
        source=${file%.*}
        moved=${source/$working_dir/$move_to}
        mkdir -pv "$moved"
        mv "$file" "$moved"  #frames per seconds = every 30 seconds
        #ffmpeg -i "$moved"/"${file##*/}" -vf fps=1/30 "$moved"/"${file##*/}"-%04d.jpg
        #or
        ffmpeg -i "$moved"/"${file##*/}" -vf fps=1 "$moved"/"${file##*/}"-%04d.jpg
  fi
 done

Tested:

strips off what it needs to in order to look where they are at, and put it where you want it, then created multi frames attaching the filename to the number, so when one looks at the image file they will know what or where it came from, and is pertaining to.

mod:
Code:

image2
is for making movies out of images.

https://ffmpeg.org/ffmpeg-formats.html#Examples-1

AwesomeMachine 06-09-2018 12:40 PM

#5, I thought he just wanted the output put in the working directory.

BW-userx 06-09-2018 12:42 PM

...

ericlindellnyc 06-10-2018 01:23 PM

thanks to all who have offered suggestions. I will be trying them out and reporting back in short order.

ericlindellnyc 06-13-2018 10:07 AM

Implemented Suggestions. Frame to JPG Convert Stopped Early
 
Thanks to all for great suggestions.

Quote:

Originally Posted by BW-userx (Post 5865484)
[code]
Code:

#!/bin/bash
working_dir=/media/data/testMovies
move_to=/media/data/rdThumbNailed
script_dir=/home/userx/scripts
for file in "$working_dir"/* ;
do
  if [[ -f "$file" ]]; then
    source=${file%.*}
    move_to=${source/$working_dir/$move_to}
    mkdir -pv "$move_to"
    mv "$file" "$move_to"
  ffmpeg -i "$move_to"/"${file##*/}" -y -f image2 -c:v mjpeg
"$move_to"/"${file##*/}"-%03d.jpg
  fi
done


I pasted the foregoing code at command prompt.
This created the first 9870 JPGs from the first video,
stopping way early near 10,000th frame .. hmmm.

Below is edited terminal output -- two errors highlighted, as follows ..
1] "Output file #0 does not contain any stream." -- AND --
2] "[adp @ 0xfb8400] Format adp detected only with low score of 25,
misdetection possible!"

I changed -%03d.jpg to -%05d.jpg, for more JPG names. Didn't help.

Any suggestions why it's stopping after 9870th frame much appreciated !!
Thanks in advance.

[ *** BEGIN TERMINAL OUTPUT *** ]

9790 fps= 37 q=24.8 size=N/A time=00:02:43.32 bitrate=N/A dup=2 drop=0 frame= 9810 fps= 37 q=24.8 size=N/A
[...SNIP...]
frame= 9870 fps= 37 q=24.8 Lsize=N/A time=00:02:44.66 bitrate=N/A dup=2 drop=0
video:535625kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
[...SNIP...]


[ *** ERROR MESSAGE *** ]
Output file #0 does not contain any stream


mkdir: created directory '/media/data/rdThumbNailed/MVI_0001/MVI_0004/MVI_0008-j'
ffmpeg version 2.8.14-0ubuntu0.16.04.1 Copyright (c) 2000-2018 the FFmpeg developers
built with gcc 5.4.0 (Ubuntu 5.4.0-6ubuntu1~16.04.9) 20160609
configuration: --prefix=/usr --extra-version=0ubuntu0.16.04.1 --build-suffix=-ffmpeg --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu
[...SNIP...]
--enable-libass --enable-libbluray --enable-libbs2b
[...SNIP...]
-x11grab --enable-libdc1394 --enable-libiec61883 --enable-libzmq --enable-frei0r --enable-libx264 --enable-libopencv
WARNING: library configuration mismatch
avcodec configuration: --prefix=/usr --extra-version=0ubuntu0.16.04.1 --build-suffix=-ffmpeg --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --cc=cc --cxx=g++ --enable-gpl --enable-shared
[...SNIP...]
enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libvo_aacenc --enable-libvo_amrwbenc
libavutil 54. 31.100 / 54. 31.100
[...SNIP...]
libpostproc 53. 3.100 / 53. 3.100


[ *** ERROR MESSAGE *** ]
[adp @ 0xfb8400] Format adp detected only with low score of 25, misdetection possible!


Input #0, adp, from '/media/data/rdThumbNailed/MVI_0001/MVI_0004/MVI_0008-j/MVI_0008-j.MP4':
Duration: 02:40:42.12, start: 0.000000, bitrate: 438 kb/s
Stream #0:0: Audio: adpcm_dtk, 48000 Hz, stereo, s16p
Output #0, image2, to '/media/data/rdThumbNailed/MVI_0001/MVI_0004/MVI_0008-j/MVI_0008-j.MP4-%05d.jpg':


[ *** ERROR MESSAGE *** ]
Output file #0 does not contain any stream


eric-HP-Compaq-dc7900-Small-Form-Factor eric # for file in "$working_dir"/* ; do if [[ -f "$file" ]]; then source=${file%.*} ; move_to=${source/$working_dir/$move_to}; mkdir -pv "$move_to"; mv "$file" "$move_to"; ffmpeg -i "$move_to"/"${file##*/}" -y -f image2 -c:v mjpeg "$move_to"/"${file##*/}"-%05d.jpg; fi; done

BW-userx 06-13-2018 11:45 AM

Quote:

Originally Posted by ericlindellnyc (Post 5867052)
Thanks to all for great suggestions.

I pasted the foregoing code at command prompt.
This created the first 9870 JPGs from the first video,
stopping way early near 10,000th frame .. hmmm.

Below is edited terminal output -- two errors highlighted, as follows ..
1] "Output file #0 does not contain any stream." -- AND --
2] "[adp @ 0xfb8400] Format adp detected only with low score of 25,
misdetection possible!"

I changed -%03d.jpg to -%05d.jpg, for more JPG names. Didn't help.

Any suggestions why it's stopping after 9870th frame much appreciated !!
Thanks in advance.

top of head guess, if it is doing this with just one the same one, bad file. if that is a true, then try re-sampling the movie using perhaps handbrake to fix it, maybe, hopefully. anything other than that I'd have to research it. something you can do. ;)

https://ffmpeg.org/ffmpeg.html

search for limitations on that page. it says something about stream picking. I didn't read it all.

ericlindellnyc 06-13-2018 03:43 PM

So here's a few things I tried since last time ..

I tried different video files. No difference. This has worked before with MP4s.
I tried adding this switch: "-err_detect ignore_err" -- still no difference.
I checked -ss option, which someone recommended. Doesn't seem to apply.
"-map 1:a" -- possibly relevant. Don't quite understand it yet.

Checked the ffmpeg documentation page you linked. Found this, re specify codec -- MP4?

Stream handling is independent of stream selection, with an exception for subtitles described below. Stream handling is set via the -codec option addressed to streams within a specific output file. In particular, codec options are applied by ffmpeg after the stream selection process and thus do not influence the latter. If no -codec option is specified for a stream type, ffmpeg will select the default encoder registered by the output file muxer.

also looking into VLC -- which can output frames from a video. But can it do so in batch for multiple videos? Still checking

Thanks again for your helpful insights.

BW-userx 06-13-2018 03:51 PM

Quote:

Originally Posted by ericlindellnyc (Post 5867206)
So here's a few things I tried since last time ..

I tried different video files. No difference. This has worked before with MP4s.
I tried adding this switch: "-err_detect ignore_err" -- still no difference.
I checked -ss option, which someone recommended. Doesn't seem to apply.
"-map 1:a" -- possibly relevant. Don't quite understand it yet.

Checked the ffmpeg documentation page you linked. Found this, re specify codec -- MP4?

Stream handling is independent of stream selection, with an exception for subtitles described below. Stream handling is set via the -codec option addressed to streams within a specific output file. In particular, codec options are applied by ffmpeg after the stream selection process and thus do not influence the latter. If no -codec option is specified for a stream type, ffmpeg will select the default encoder registered by the output file muxer.

also looking into VLC -- which can output frames from a video. But can it do so in batch for multiple videos? Still checking

Thanks again for your helpful insights.

how big/hours, minutes is your file, and what format is it?
maybe I'll find something just as long and make sure its the same format and mess about with it to see what I see.

ericlindellnyc 06-13-2018 06:14 PM

Quote:

Originally Posted by BW-userx (Post 5867211)
how big/hours, minutes is your file, and what format is it? maybe I'll find something just as long and make sure its the same format and mess about with it to see what I see.

  • The files are almost all MP4s, with a few 3GPs.
  • They range from a few megabytes to 4 gb.
  • Duration from under a minute to about 15 minutes.

Please bear in mind that in OP, I gave the ffmpeg command that has been working successfully when run on a single file. What I've been trying to do in this thread is obtain the same functionality processing videos in batch.

Code:

ffmpeg -i putin.mp4 -y -f image2 -c:v mjpeg %03d.jpg
Thank you again for your kind assistance.

BW-userx 06-13-2018 06:46 PM

Quote:

Originally Posted by ericlindellnyc (Post 5867262)
  • The files are almost all MP4s, with a few 3GPs.
  • They range from a few megabytes to 4 gb.
  • Duration from under a minute to about 15 minutes.

Please bear in mind that in OP, I gave the ffmpeg command that has been working successfully when run on a single file. What I've been trying to do in this thread is obtain the same functionality processing videos in batch.

Code:

ffmpeg -i putin.mp4 -y -f image2 -c:v mjpeg %03d.jpg
Thank you again for your kind assistance.

just plug this in using your old stuff
Code:

ffmpeg -i "$moved"/"${file##*/}" -y -f image2 -c:v mjpeg "$moved"/"${file##*/}"-%07d.jpg #changed the number for zeros placements
it's getting me past mp4-0140657.jpg' and still going, adding -%07d.jpg - in case you didn't notice it in the code block.


All times are GMT -5. The time now is 07:13 AM.