My scripts for startup, dmenu, and the command line
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

splitchapters 3.6 KiB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. #!/bin/bash
  2. # Copied from Eloise Speight's Stack Exchange answer
  3. # script to convert m4b (audiobook) files with embedded chapted (for eg. converted from Audbile) into individual chapter files
  4. # required: ffmpeg; jg (json interpreter) & AtomicParsley (to embed pictures and add additional metadata to m4a/m4b AAC files)
  5. # discover the file type (extension) of the input file
  6. ext=${1##*.}
  7. echo "extension: $ext"
  8. # all files / folders are named based on the "shortname" of the input file
  9. shortname=$(basename "$1" ".$ext")
  10. picture=$shortname.jpg
  11. chapterdata=$shortname.dat
  12. metadata=$shortname.tmp
  13. echo "shortname: $shortname"
  14. # if an output type has been given on the command line, set parameters (used in ffmpeg command later)
  15. if [[ $2 = "mp3" ]]; then
  16. outputtype="mp3"
  17. codec="libmp3lame"
  18. elif [[ $2 = "m4a" ]]; then
  19. outputtype="m4a"
  20. codec="copy"
  21. else
  22. outputtype="m4b"
  23. codec="copy"
  24. fi
  25. echo "outputtype: |$outputtype|"
  26. # if it doesn't already exist, create a json file containing the chapter breaks (you can edit this file if you want chapters to be named rather than simply "Chapter 1", etc that Audible use)
  27. [ ! -e "$chapterdata" ] && ffprobe -loglevel error \
  28. -i "$1" -print_format json -show_chapters -loglevel error -sexagesimal \
  29. >"$chapterdata"
  30. read -p "Now edit the file $chapterdata if required. Press ENTER to continue."
  31. # comment out above if you don't want the script to pause!
  32. # read the chapters into arrays for later processing
  33. readarray -t id <<< $(jq -r '.chapters[].id' "$chapterdata")
  34. readarray -t start <<< $(jq -r '.chapters[].start_time' "$chapterdata")
  35. readarray -t end <<< $(jq -r '.chapters[].end_time' "$chapterdata")
  36. readarray -t title <<< $(jq -r '.chapters[].tags.title' "$chapterdata")
  37. # create a ffmpeg metadata file to extract addition metadata lost in splitting files - deleted afterwards
  38. ffmpeg -loglevel error -i "$1" -f ffmetadata "$metadata"
  39. artist_sort=$(sed 's/.*=\(.*\)/\1/' <<<$(cat "$metadata" |grep -m 1 ^sort_artist))
  40. album_sort=$(sed 's/.*=\(.*\)/\1/' <<<$(cat "$metadata" |grep -m 1 ^sort_album))
  41. rm "$metadata"
  42. # create directory for the output
  43. mkdir -p "$shortname"
  44. echo -e "\fID\tStart Time\tEnd Time\tTitle\t\tFilename"
  45. for i in ${!id[@]}; do
  46. let trackno=$i+1
  47. # set the name for output - currently in format <bookname>/<tranck number>
  48. outname="$shortname/$(printf "%02d" $trackno). $shortname - ${title[$i]}.$outputtype"
  49. #outname=$(sed -e 's/[^A-Za-z0-9._- ]/_/g' <<< $outname)
  50. outname=$(sed 's/:/_/g' <<< $outname)
  51. echo -e "${id[$i]}\t${start[$i]}\t${end[$i]}\t${title[$i]}\n\t\t$(basename "$outname")"
  52. ffmpeg -loglevel error -i "$1" -vn -c $codec \
  53. -ss ${start[$i]} -to ${end[$i]} \
  54. -metadata title="${title[$i]}" \
  55. -metadata track=$trackno \
  56. -map_metadata 0 -id3v2_version 3 \
  57. "$outname"
  58. [[ $outputtype == m4* ]] && AtomicParsley "$outname" \
  59. --artwork "$picture" --overWrite \
  60. --sortOrder artist "$artist_sort" \
  61. --sortOrder album "$album_sort" \
  62. > /dev/null
  63. done