wav2sbc:wav格式转成sbc的txt格式

有些蓝牙音频设备的本地音乐需要用到sbc格式,比如恒玄(BES)的蓝牙耳机,如果是从事BES平台开发的同学肯定都非常了解吧,他们的本地音频使用的就是txt形式的sbc格式,而且还是单声道16比特,16KHz采样率的的sbc格式

实现思路

因为我个人平时使用Unix系统比较多,比如Macos和Ubuntu,所以我着重考虑如何在Unix平台上实现这种音频转换,其实很多带界面的工具使用起来也比较简案,但是个人认为命令工具效率很更高,尤其是在批量操作的时候,优势则更加明显,作为不怎么喜欢用鼠标的技术宅,能命令行就命令行吧

我能想到的有二种思路:

  1. 找一些wav编码成sbc的开源代码,这些开源代码基本上都是用C/C++实现的,把这些代码整合到自己项目中来,比如ffmpeg的编解码器等,然后用C调用这些编解码函数。但是这种实现非常麻烦,尤其是对于初学音频的人来说
  2. 第二种方案是自己用脚本来实现,我们知道ffmpeg是一款非常强大的音视频处理软件,我们直接在shell上调用ffmpeg命令就可以实现wav到sbc的格式转化,但是不能得到sbc的txt形式,不过后面这部分工作我们可以用脚本来实现,这种方案非常简单,而且不用懂音频知识都可以实现

环境安装

我现在使用的是Ubuntu的环境,由于Ubuntu默认情况下并没有安装ffmpeg,但是安装命令也非常简单

$ sudo apt-get install ffmpeg -y	

先来查看下我的测试音频

$ ffmpeg -i test.wav
Input #0, wav, from 'test.wav':
  Duration: 00:00:01.91, bitrate: 1536 kb/s
    Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 48000 Hz, 2 channels, s16, 1536 kb/s

可以看出我的音频文件是48KHz采样率,双声道,16比特的格式

现在需要将其转化成16KHz采样率,单声道,16比特的sbc文件,输入命令如下

$ ffmpeg -i test.wav -ar 16000 -ac 1 test.sbc
Stream mapping:
  Stream #0:0 -> #0:0 (pcm_s16le (native) -> sbc (native))
Press [q] to stop, [?] for help
Output #0, sbc, to 'test.sbc':
  Metadata:
    encoder         : Lavf58.45.100
    Stream #0:0: Audio: sbc, 16000 Hz, mono, s16, 128 kb/s
    Metadata:
      encoder         : Lavc58.91.100 sbc
size=      30kB time=00:00:01.91 bitrate= 128.0kbits/s speed= 513x
video:0kB audio:30kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.000000%

我们再查看下test.sbc的格式

$ ffmpeg -i test.sbc
Input #0, sbc, from 'test.sbc':
  Duration: N/A, start: 0.000000, bitrate: N/A
    Stream #0:0: Audio: sbc, 16000 Hz, mono, s16

已经是单声道,16KHz采样率,16比特的sbc文件了

我们现在继续将这个sbc文件转化成TXT格式

#! /usr/bin/python

import sys
import os

input = "test.sbc"
# 读sbc文件
with open(input, "rb") as f:
    content = f.read()

out = ""
# 将其转化成Hex形式的TXT文件
for i in range(len(content)):
    if i % 16 == 0 and i != 0:
        out += "\n";
    out += "0x%02x," % ord(content[i])

output = os.path.splitext(input)[0] + ".txt"
# 输出到文件 test.txt
with open(output, "w+") as f:
    f.write(out)

print("done")

test.txt文件就是我们想要的文件

功能整合

现在我们把这2部分工作整合到一个Python脚本中来实现吧

#! /usr/bin/python
#coding=utf-8

# Filename: wav2sbc.py

import sys
import os

def transfer(input):
    # 读sbc文件
    with open(input, "rb") as f:
        content = f.read()

    out = ""
# 将其转化成Hex形式的TXT文件
    for i in range(len(content)):
        if i % 16 == 0 and i != 0:
            out += "\n";
        out += "0x%02x," % ord(content[i])

    output = os.path.splitext(input)[0] + ".txt"
# 输出到文件 test.txt
    with open(output, "w+") as f:
        f.write(out)

def wav2sbcHex(wavFilename):
    sbcFilename = os.path.splitext(wavFilename)[0] + ".sbc"
    cmd = "ffmpeg -i %s -ar 16000 -ac 1 %s" % (wavFilename, sbcFilename)
    os.popen(cmd)
    if os.path.isfile(sbcFilename):
        print("Wav Transfer sbc Successfully");
    else:
        print("Wav Transfer sbc Error")
        exit(1)

    transfer(sbcFilename)
    txtFilename = os.path.splitext(sbcFilename)[0] + ".txt"
    if os.path.isfile(txtFilename):
        print("Sbc Transfer Hex txt Successfully")
        print("Done")
    else:
        print("Sbc Transfer Hex txt Error")
        exit(1)

if __name__ == "__main__":
    for wavFilename in sys.argv[1:]:
        wav2sbcHex(wavFilename)

这个脚本接收命令行参数作为输入,输出对应的sbc文件和txt文件

$ ./wav2sbc.py test.wav
Wav Transfer sbc Successfully
Sbc Transfer Hex txt Successfully
Done

上面的命令在当前目录生成test.sbctest.txt文件

如果想要实现批量转化也非常简单,下面的命令可以一次性转化当前目录下所有的wav文件

$ ls *.wav | xargs ./wav2sbc.py
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值