4

i want to split a video file by size using ffmpeg.

Do you know how to do that ?

Do i have to calculate the duration that corresponds to each size ?

Thank you.

1
  • are you trying to do this programmatically (i.e. you're writing code using FFMPEG and you want to do that) or are you just wanting to split the file?
    – txtechhelp
    Feb 5, 2014 at 22:06

3 Answers 3

4

The -fs option limits the file size. The number is supplied in bytes. If you do not wish to re-encode, use the -copy option.

Unfortunately, I'm not aware of how to seek to the byte position for starting the next video. But you could check resulting duration and start the next encoding using the -ss option to start encoding from there onwards.

4

I just had the same problem, and after I didn't find a solution here, I wrote a quick bash script for that job.

Features:

  • Use ffmpeg's -fs-flag to limit filesize
  • Check length of resulting video part and calculate where to start next part
  • Enumerate video parts
  • proceed with as many parts as needed to contain the whole source file.
  • Allow for custom ffmpeg arguments to also reduce resolution and quality in one pass.

It takes only three arguments: The source filename, the desired filesize of each part and the desired arguments for ffmpeg.

Example call to split a file into 64MB parts:

./split-video.sh huge-video.mov 64000000 "-c:v libx264 -crf 23 -c:a copy -vf scale=960:-1"

Finally, the source code of the script:

#!/bin/bash
# Short script to split videos by filesize using ffmpeg by LukeLR

if [ $# -ne 3 ]; then
    echo 'Illegal number of parameters. Needs 3 parameters:'
    echo 'Usage:'
    echo './split-video.sh FILE SIZELIMIT "FFMPEG_ARGS'
    echo 
    echo 'Parameters:'
    echo '    - FILE:        Name of the video file to split'
    echo '    - SIZELIMIT:   Maximum file size of each part (in bytes)'
    echo '    - FFMPEG_ARGS: Additional arguments to pass to each ffmpeg-call'
    echo '                   (video format and quality options etc.)'
    exit 1
fi

FILE="$1"
SIZELIMIT="$2"
FFMPEG_ARGS="$3"

# Duration of the source video
DURATION=$(ffprobe -i "$FILE" -show_entries format=duration -v quiet -of default=noprint_wrappers=1:nokey=1|cut -d. -f1)

# Duration that has been encoded so far
CUR_DURATION=0

# Filename of the source video (without extension)
BASENAME="${FILE%.*}"

# Extension for the video parts
#EXTENSION="${FILE##*.}"
EXTENSION="mp4"

# Number of the current video part
i=1

# Filename of the next video part
NEXTFILENAME="$BASENAME-$i.$EXTENSION"

echo "Duration of source video: $DURATION"

# Until the duration of all partial videos has reached the duration of the source video
while [[ $CUR_DURATION -lt $DURATION ]]; do
    # Encode next part
    echo ffmpeg -i "$FILE" -ss "$CUR_DURATION" -fs "$SIZELIMIT" $FFMPEG_ARGS "$NEXTFILENAME"
    ffmpeg -ss "$CUR_DURATION" -i "$FILE" -fs "$SIZELIMIT" $FFMPEG_ARGS "$NEXTFILENAME"

    # Duration of the new part
    NEW_DURATION=$(ffprobe -i "$NEXTFILENAME" -show_entries format=duration -v quiet -of default=noprint_wrappers=1:nokey=1|cut -d. -f1)

    # Total duration encoded so far
    CUR_DURATION=$((CUR_DURATION + NEW_DURATION))

    i=$((i + 1))

    echo "Duration of $NEXTFILENAME: $NEW_DURATION"
    echo "Part No. $i starts at $CUR_DURATION"

    NEXTFILENAME="$BASENAME-$i.$EXTENSION"
done

Hope, that helps :)

1
  • 1
    You can add if [[ $? -ne 0 ]]; then exit 1; fi just after the call to ffmpeg, to avoid a problem where you try to interrupt the transcoding process but the bash loop keeps running. Oct 26, 2019 at 16:19
0

I found the video-splitter on GitHub to be extremely useful. Here's how I successfully split videos based on file size:

find . -type f -size +3900M -exec python ffmpeg-split.py -f '{}' -S 3900000000 -e '-threads 4' \;

The purpose of this command is to locate files larger than 3.9G and divide them into smaller parts of 3900000000 bytes (3.6G) each. This is done to ensure that the files can be copied to FAT32 disks.

You must log in to answer this question.

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