22 August 2022

bilibili-downloaded.png

在B站(Bilibili)听到好听的音乐想要下载但不知如何操作?以下是本人于 2022-08-22 亲 测可用于 安卓11 + 哔哩哔哩手机应用版本3.13.0 的方法。其实过程很简单:就是在哔哩哔 哩手机应用里缓存想要下载的音乐,然后找到相应的目录把对应的视频、音频文件复制出来。 问题就是第二步稍微有点曲折。

对我来说,这么折腾的主要动机是:

  • 自驾游时音乐不会因没手机信号而中断。
  • 手机连上 Andriod Auto 的时候,可以用 Youtube Music 方便的选歌。(哔哩哔哩缓存 歌曲的管理功能太简陋了)。

下面是具体的步骤:

  1. 在哔哩哔哩的手机应用里把中意的视频缓存到手机。
    • 虽然缓存到手机后理论上就可以离线观看了,但我觉得实际使用还是多有不便。所以 我希望能把音乐复制出来导入其它播放器中。因此继续下一步。
  2. 继续在哔哩哔哩的手机应用中,前往 我的 》离线缓存 》右上角齿轮图标 》 离线诊 断 然后点击想要的视频。注意查看
    存储目录
    应该是 手机默认存储
    文件结构
    记住文件夹的名字
  3. 把手机连上电脑(MacBook 的话用一个叫做 Android File Transfer 的工具)打开手机 目录 Android/data/com.bilibili.app.in/download 然后进入到上一步所记录的文件 夹并按照 文件结构 的指引找到 audio.m4s 和/或 video.m4s 并复制即可。
    • 之所以要连到电脑上是因为安卓11里直接用手机上的文件管理器是看不到 Android/data/ 下有任何文件的。如果目录 不是 默认的位置,而是一个手机可 以直接访问的目录则不必连电脑。
    • 为了能被其它应用打开,audio.m4s 和 video.m4s 可能需要改名。音视频编解码我不 太熟;如果理解没错的话,两个文件都可以直接更名为 *.mp4 (但播放器需要支持 相应的编码才行)。

      $ ffmpeg -i audio.m4s
      Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'audio.m4s':
        Metadata:
          major_brand     : iso5
          minor_version   : 1
          compatible_brands: avc1iso5dsmsmsixdash
          encoder         : Lavf57.71.100
          description     : Packed by Bilibili XCoder v2.0.2
        Duration: 00:05:07.14, start: 0.000000, bitrate: 129 kb/s
        Stream #0:0[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 2 kb/s (default)
      ...
      $ ffmpeg -i video.m4s
      Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'video.m4s':
        Metadata:
          major_brand     : iso5
          minor_version   : 1
          compatible_brands: iso5dsmsmsixdash
          encoder         : Lavf57.71.100
          description     : Packed by Bilibili XCoder v2.0.2
        Duration: 00:05:07.12, start: 0.040000, bitrate: 487 kb/s
        Stream #0:0[0x1](und): Video: hevc (Main) (hev1 / 0x31766568), yuv420p(tv, bt709), 1280x720 [SAR 1:1 DAR 16:9], 1 kb/s, 25 fps, 25 tbr, 16k tbn (default)
      ...
      

相比缓存一首导出一首,我一般是攒若干首歌曲然后用 shell 命令一次性全部转换成 aac 格式的音乐文件里(然后 m4s 文件就可以删掉了)。

for each in $(find . -name 'audio.m4s'); do
    folder=$(echo $each | cut -d / -f2)
    name=$(find $folder -name entry.json -exec jq -r .title {} \;)
    ffmpeg -i $each -acodec copy "${name}.aac"
done


blog comments powered by Disqus