3

I have a bunch of .mp4 files (DRM free). Each file comprises two episodes of a kids TV show. I would like to simply split the file in two without re-encoding. What's the best way to do this? Preferably with a GUI (as I need to skip to the correct part of each file to find the divider between the two episodes).

Thanks,

2 Answers2

7

I recommend opening the video in a media player to find the time where you want to split it. Then you can use ffmpeg with the following script. It does not re-encode the video.

#!/bin/bash

Split Video Script

Usage: script_name file_name split-point

Example: split_video_script bugs_bunny.mp4 31:23

Instructions:

1. Type the name of your script (if it is already added to ~/bin and marked as executable).

2. Type the file name including path to it if necessary.

3. Type the time where you want to split the video. It goes in minutes:seconds

Get length in seconds

length=$(echo "$2" | awk -F: '{print ($1 * 60) + $2}')

Get filename without extension

fname="${1%.*}"

First half

ffmpeg -i "${fname}.mp4" -c copy -t "$length" "${fname}1.mp4"

Second half

ffmpeg -i "${fname}.mp4" -c copy -ss "$length" "${fname}2.mp4"

Update: I recently needed to update this script because of an issue with the second half. So, now I have to process the second half of it. You would add in the parameters that are specific to your original video. You can use mediainfo, ffprobe or ffmpeg -i to find the needed information about your original video.

#!/bin/bash

if [ -z "$1" ]; then echo "Usage: $0 file-name" exit 1 fi

read -p "Enter time to split video (hh:mm:ss.mmm) " split_time

ext="${1##.}" fname="${1%.}"

First half

ffmpeg -i "$1" -c copy -t "$split_time" -c:s copy "${fname}1.${ext}"

Second half

ffmpeg -ss "$split_time" -i "$1" -c:v libx264 -crf 17 -preset veryfast -r 30 -s 1920x1080 -c:a aac -ac 2 -b:a 256k -ar 44100 -pix_fmt yuv420p -movflags faststart -c:s copy "${fname}2.${ext}"

jbrock
  • 3,417
0

I needed to use your script to split a video into thirds instead of splitting the mp4 into two. Here is my version of the script:

#!/bin/bash

NUM_OF_SPLITS=3

main() { # Requires: $ brew install ffmpeg

# total length in seconds 
total_length=$(ffprobe -v quiet -of csv=p=0 -show_entries format=duration "$1")

# Get filename without extension
fname="${1%.*}"
split_time=$(echo "$total_length"/"$NUM_OF_SPLITS" | bc -l)

declare -a start_times
declare -a end_times

for((i=0; i < $num_of_splits; i++)); do
    local output_file="${fname}_"part$i".mp4"
    if [[ "$i" -eq 0 ]]; then
        local start_time=0
        local end_time="$split_time"

        ffmpeg -i "${fname}.mp4" -c copy -t "$end_time" "$output_file"
    else
        local start_time="${end_times[$i-1]}"
        local end_time=$(echo "$start_time "*" 2" | bc -l)

        # echo "Start time: $start_time"
        # echo "End time: $end_time"

        ffmpeg -ss "$start_time" -to "$end_time"  -i "${fname}.mp4" -c copy "$output_file"
    fi

    start_times+=($start_time)
    end_times+=("$end_time")
done

}

Split Video Script

Example: split_video_script bugs_bunny.mp4

Instructions:

1. Type the name of your script (if it is already added to ~/bin and marked as executable).

2. Type the file name including path to it if necessary.

main "$1"