DEV Community

Anton
Anton

Posted on

How to cut an mp3 file into multiple audios with bash and ffmpeg according to a timetable.

I have a timetable in a text file that looks like this:

00:05 - 00:54 Dédicace, À léon werth

00:54 - 01:37 Premier chapitre. Lorsque j'avais six ans

01:36 - 02:06 J'ai montré mon chef-d'œuvre

I'm trying to cut an mp3 file into multiple small ones according to this timetable, so the requirements are:

  1. I want to do it with bash. I have learned how to do one file. But a timetable is out of my current bash skills.
  2. The column with words serve as the names for files.
  3. I would like the files to be enumerated like this: 01.Dédicace_À_léon_werth.mp3 02.Premierchapitre_Lorsque_j'avais_six_ans.mp3

And so on.

Oldest comments (4)

Collapse
 
missamarakay profile image
Amara Graham

My coworker did something similar, but in python. Not sure it will help, but here is a link to his post with code snippets: medium.com/@SamuelCouch/using-mach...

Collapse
 
antonrich profile image
Anton

This is not exactly what I want in this case, however, using Watson for synchronizing text and audio is awesome. Thanks.

Collapse
 
lucifer1004 profile image
Gabriel Wu • Edited

I think all your requirements have been met.

#!/bin/bash
# split.sh

TIMETABLE="timetable.txt"
INPUT="input.mp3"
NUM=0

while getopts t:i: option 
do
  case "${option}" 
  in
    t) TIMETABLE=${OPTARG};;
    i) INPUT=${OPTARG};;
  esac
done

while read CMD; do
  let NUM=NUM+1
  START=$(echo "$CMD" | awk '{printf("00:%s", $1)}')
  END=$(echo "$CMD" | awk '{printf("00:%s", $3)}')
  FILENAME=$(printf "%02d" $NUM).$(echo "$CMD" | awk -f filename.awk)
  ffmpeg -i "$INPUT" -ss "$START" -t "$END" -acodec copy "$FILENAME"
done < "$TIMETABLE"

The default timetable is timetable.txt, and the default input is input.mp3, however, you can specify other files with options -t for timetables and -i for .mp3 files.

And here is the awk script file used in the shell script.

# filename.awk
{
  for (i=4; i < NF; i++) {
    gsub(/[\.,]/, "", $i)
    if (i < NF-1) printf("%s_", $i)
    else printf("%s", $i)
  }
  printf(".mp3")
}
Collapse
 
antonrich profile image
Anton

Big big thank you man.