0

I am trying to figure out which distro this script (scene_splitter.sh) was built for. Everytime I try to use it I get the following error.

x@x-pc:/media/x/WD_2TB_HDD/test$ ./scene_splitter.sh 001.mp4
==============================================================================
FILE START: 001.mp4
mkdir: cannot create directory ‘./001.mp4’: File exists
Finding Scene... this might take a while...
./scene_splitter.sh: line 12: ./001.mp4/ffout.tmp.txt: Not a directory
Filtering timestamp... this might take a while...
./scene_splitter.sh: line 15: ./001.mp4/timestamps.tmp.txt: Not a directory
grep: ./001.mp4/ffout.tmp.txt: Not a directory
./scene_splitter.sh: line 17: ./001.mp4/timestamps.tmp.txt: Not a directory
Found  scenes
./scene_splitter.sh: line 31: ./001.mp4/timestamps.tmp.txt: Not a directory
---------------------------------------------------------------------------
LAST SCENE START:0/ (0,end)
ffmpeg version 3.4.4-0ubuntu0.18.04.1 Copyright (c) 2000-2018 the FFmpeg developers
  built with gcc 7 (Ubuntu 7.3.0-16ubuntu3)
  configuration: --prefix=/usr --extra-version=0ubuntu0.18.04.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --enable-gpl --disable-stripping --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librubberband --enable-librsvg --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-omx --enable-openal --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libopencv --enable-libx264 --enable-shared
  libavutil      55. 78.100 / 55. 78.100
  libavcodec     57.107.100 / 57.107.100
  libavformat    57. 83.100 / 57. 83.100
  libavdevice    57. 10.100 / 57. 10.100
  libavfilter     6.107.100 /  6.107.100
  libavresample   3.  7.  0 /  3.  7.  0
  libswscale      4.  8.100 /  4.  8.100
  libswresample   2.  9.100 /  2.  9.100
  libpostproc    54.  7.100 / 54.  7.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '001.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.20.100
  Duration: 00:04:17.77, start: 0.000000, bitrate: 4771 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x1080 [SAR 9:8 DAR 2:1], 4635 kb/s, 29.97 fps, 29.97 tbr, 30k tbn, 59.94 tbc (default)
    Metadata:
      handler_name    : VideoHandler
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
./001.mp4/001.mp4.(0 of ).mp4: Not a directory
LAST SCENE DONE:0/ (0,end)
---------------------------------------------------------------------------
FILE DONE: 001.mp4
==============================================================================

It seems it was built for using with a distro that allows a folder and a file to have the same exact name, only difference being one a folder and one a file... assuming that distro knows the difference and thus allows it.


Here is the code for scene_splitter.sh

#/bin/bash

start=0; 
count=0; 
in="$1"
bn="$(basename "$in")"
echo "=============================================================================="
echo "FILE START: $bn"
mkdir "./$bn"

echo "Finding Scene... this might take a while..."
ffmpeg -nostdin -i "$in" -filter:v "select='gt(scene,0.1)',showinfo" -f null - 2>"./$bn/ffout.tmp.txt"

echo "Filtering timestamp... this might take a while..."
grep showinfo "./$bn/ffout.tmp.txt" | grep pts_time:[0-9.]* -o | grep '[0-9]*\.[0-9]*' -o > "./$bn/timestamps.tmp.txt"

scenes=$(wc -l < "./$bn/timestamps.tmp.txt")
echo "Found $scenes scenes"
sleep 1

while IFS= read -r line; do
    echo "---------------------------------------------------------------------------"
    echo "SCENE START: $count/$scenes ($start,$line)"
    ffmpeg -i "$in" -ss "$start" -to "$line" -nostdin -y -vcodec libx264 -acodec aac -g 120 -s 1280x720 -r 30 "./$bn/$bn.($count of $scenes).mp4"
    echo "SCENE DONE:$count/$scenes ($start,$line)"
    echo "---------------------------------------------------------------------------"
    start=$line
    count=$(($count+1))
    sleep 1

done <"./$bn/timestamps.tmp.txt"
echo "---------------------------------------------------------------------------"
echo "LAST SCENE START:$count/$scenes ($start,end)"
ffmpeg -i "$in" -ss "$start" -nostdin -y -vcodec libx264 -acodec aac -g 120 -s 1280x720 -r 30 "./$bn/$bn.($count of $scenes).mp4"
echo "LAST SCENE DONE:$count/$scenes ($start,end)"
echo "---------------------------------------------------------------------------"

echo "FILE DONE: $bn"
echo "=============================================================================="

Does anyone know how to edit this script so that it doesn't want to create a directory with the exact same name as the file being inputted?

  • I feel like I am going to have to agree with you. However, that doesn't seem to be the case since the script doesn't try to do what you suggest. – Anonymous User Feb 8 at 4:49
  • So replace all of the $bn with bn="${in%.*}" ? – Anonymous User Feb 8 at 4:53
  • Do you think you can try to do it and post the code as an answer? If it works ill vote it, of course. Thanks! – Anonymous User Feb 8 at 4:54
  • It's not possible to create a file and a folder under the same directory with the same name. It's kernel level restriction. And shell scripts are usually not built to run on a specific distro. If you have any questions about that script, tell people which part you don't understand instead of asking an X-Y question. – 炸鱼薯条德里克 Feb 8 at 4:55
1

Creating a directory with the same name as a file is not really possible on any Linux or Unix (that I know of, at least.)

But that's not really what the script is trying to do.

If you look carefully, you'll notice it's creating a directory with the same basename of the input file, but on the current directory.

Look at this part:

bn="$(basename "$in")"
# ...
mkdir "./$bn"

So, if given an input file of /path/to/movies/001.mp4 or ../movies/001.mp4, then it will try to create the ./001.mp4 directory, which is different from the input file (assuming your in a directory other than /path/to/movies in the example I used.)

The script is expecting you're running it from the output directory, and that the input files live in a separate directory other than the current one.

For example, this usage should work fine for you:

x@x-pc:/media/x/WD_2TB_HDD/test$ mkdir output
x@x-pc:/media/x/WD_2TB_HDD/test$ cd output
x@x-pc:/media/x/WD_2TB_HDD/test/output$ ../scene_splitter.sh ../001.mp4

UPDATE: If you want to modify the script to avoid the name clash, simply changing how bn is defined should do the job. For instance, adding an out- prefix:

bn="out-$(basename "$in")"
  • Do you think you could just edit the script to work. You seem really skilled at this. For some reason I cannot do as you are suggesting. It's not working... – Anonymous User Feb 8 at 4:58
  • Changing bn="$(basename "$in")" to bn="out-$(basename "$in")" should make it work in the same directory, avoiding the name clash. – filbranden Feb 8 at 5:00
  • 1
    YAY!! You are awesome!! Thank you so much!! – Anonymous User Feb 8 at 5:02
  • So it seems to be creating an mp4 file for almost every dang frame? I am pretty sure this is the way it was meant to work but I need it to be able to split scenes correctly as in extract short clips from compilation videos and its doing hundreds per scene. – Anonymous User Feb 8 at 5:10
  • Sorry, I wouldn't be able to figure out more, since now it's an ffmpeg problem and I don't know it well enough to figure it out. I suggest you should post a second question about why ffmpeg isn't splitting into scenes correctly (be detailed about what you're seeing and what you expected), you'll probably find an ffmpeg expert who might be able to figure it out (and explain how scene splitting works.) Good luck! – filbranden Feb 8 at 5:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.