Skip to content

Instantly share code, notes, and snippets.

@YDX-2147483647
Created July 5, 2024 06:23
Show Gist options
  • Select an option

  • Save YDX-2147483647/c57a70c7b6f0e06e088ebed49341be8d to your computer and use it in GitHub Desktop.

Select an option

Save YDX-2147483647/c57a70c7b6f0e06e088ebed49341be8d to your computer and use it in GitHub Desktop.
Extract chapters from an audio using ffprobe.

Extract chapters from an audio using ffprobe.

Basic example

$ curl -LO https://static.thetype.cloud/typechat/typechat157.mp3
$ ffprobe typechat157.mp3
…
  Metadata:
    album           : 字谈字畅
    …
    TIT3            : ……《字谈字畅》自 2015 年开播,是全球首家用华语制作的字体排印主题播客节目,由 The Type 出品,联系方式 [email protected] ……
    encoded_by      : Forecast
    …
  Chapters:
    Chapter #0:0: start 0.000000, end 121.000000
      Metadata:
        title           : 开场
    Chapter #0:1: start 121.000000, end 379.000000
      Metadata:
        title           : 暑假字体班信息
    …
    Chapter #0:10: start 4290.000000, end 4440.000000
      Metadata:
        title           : 尾声
…

Nushell script

probe.nu:

# Format a time point as 00:00 or 1:00:00
def format-time-point [t: duration] {
  if $t >= 1hr {
    let h = $t // 1hr
    let m = ($t // 1min) mod 60
    let s = ($t // 1sec) mod 60
    $"($h):($m | fill -c '0' -w 2 -a right):($s | fill -c '0' -w 2 -a right)"
  } else {
    let m = $t // 1min
    let s = ($t // 1sec) mod 60
    $"($m | fill -c '0' -w 2 -a right):($s | fill -c '0' -w 2 -a right)"
  }
}

# Extract chapters from a MP3 audio and format it for 小宇宙
def get-chapters [file: string] {
  ffprobe $file -output_format json -show_chapters -v 0
  | from json
  | get chapters
  | each {|chapter|
      {
        title: $chapter.tags.title,
        start: ($chapter.start_time | into int),
      }
    }
  | each {|chapter|
      $"($chapter.start | into duration --unit sec | format-time-point $in) ($chapter.title)"
    }
  | str join "\n"
}

# Save chapters of all MP3 audio in the current directory into “chapters.txt”
def main [] {
  ls *.mp3
  | get name
  | reverse
  | parse "typechat{episode}.mp3"
  | get episode
  | each {
      "#" + ($in | into string) + "\n\n" + (get-chapters $"typechat($in).mp3") + "\n\n"
    }
  | tee { save --append chapters.txt }
}
$ nu probe.nu --help
Save chapters of all MP3 audio in the current directory into “chapters.txt”
…

$ nu probe.nu
╭───┬────────────────────────────────────╮
│ 0 │ #157                               │
│   │                                    │
│   │ 00:00 开场                         │
│   │ …                                  │
│   │ 1:11:30 尾声                       │
│   │                                    │
│   │                                    │
╰───┴────────────────────────────────────╯

$ cat chapters.txt
#157

00:00 开场
02:01 暑假字体班信息
06:19 新闻三则
20:43 北京 abC 书展感想
25:45 主题:隐字上海
33:41 三位摄影师的拍字实践
44:32 隐字的分类
51:23 读者的反响和互动
1:02:23 隐字书的设计
1:07:39 隐字书的正文字体和线下活动
1:11:30 尾声
@YDX-2147483647
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment