1308351.png

浮霄

GF  2024-04-08 01:49
(音声当然得笑着去听啦 >-<  愿你永葆那份欢愉)

【工具分享】关于如何解决音声左右声道不如意的问题

不知道大家听音声的时候有没有遇到过这样的情况,音声很不错,内容很精彩,尤其是(耳语/耳舔/耳呼)部分相当出色,但是。。。

为啥是(左/右)边的耳朵啊                      


众所周知,人和人的生理情况是不一样的,耳朵的敏感程度当然也逃不出这一法则。再加上经常听音声的人,本身就会因为佩戴耳机的习惯等种种外部因素影响耳朵的耐受性,久而久之,有的人会更喜欢用左耳接收吐息声偏多的声道,而有的人则会更喜欢用右耳来享受。


面对这一情况,业界有不少社团选择专门附加上声道逆转的同捆音声(重点表扬绫香姐),这自然是皆大欢喜,但依旧有大部分的社团并不会考虑这种差异化的问题,导致偶尔会出现,明明这个双声道音声全程80%的重点都在左声道,但听众恰恰是个右耳敏感的人,导致他听的非常不爽这样的情况。


一个很好的解决办法是,使用提供声道互转功能的音乐播放器(例如PotPlayer),但这个办法也有局限性,且治标不治本,如果有收藏癖的人恰好想收藏反转的音声怎么办呢?而且对于一些不想去找或者根本找不到提供类似功能的播放器的小白来说,这个方法并不友好。


另一个办法则是使用
专业的软件(比如AU)来处理音声源文件,这次倒是治本了,但仍旧避免不了那个问题,太专业了,软件里需要勾选太多东西,对于普通的听友来说,为了换个声道还得专门下个专业的处理软件,有些小题大作了。


浮霄我呢,今天就不幸的遇到了类似的情况,新买的一部haru酱的音声,文件夹上写明了右耳main,什么呼气啊,耳语啊之类的episode,基本上都在右耳这边如火如荼的展开,可是我tm是左耳敏感啊                    

这部我可是提前半个月收藏,期待了整整两周的作品,结果要因为这种理由哽住?

MD,受不了了,爆了。

很快啊,我花了大半天时间,学习了双声道音频处理的相关内容和一些必要的知识,搓了个简单好用脚本出来。如下,为了方便使用,依旧是打包成exe程序,双击就能自动批量处理,很方便。



代码顺带贴出来:
复制代码
  1. # 作者:浮霄默客
  2. # 日期:2024.4.7
  3. # 描述:交换音频左右声道
  4. import os  # 导入os库,用于操作系统相关操作,如文件和目录操作
  5. import subprocess  # 导入subprocess库,用于创建新的进程,连接到其输入/输出/错误管道,并获取其返回码
  6. # 获取当前脚本所在目录
  7. script_dir = os.path.dirname(os.path.abspath(__file__))
  8. ffmpeg_path = os.path.join(script_dir, 'ffmpeg.exe')
  9. # 定义一个列表,包含所有支持的音频格式
  10. supported_formats = ['mp3', 'wav', 'flac', 'aac', 'MP3', 'WAV', 'FLAC', 'ACC']
  11. def get_bitrate(audio_file):
  12.     # 使用ffmpeg获取比特率
  13.     # 定义ffmpeg命令行参数
  14.     cmd = [ffmpeg_path, '-i', audio_file, '-f', 'null', '-']
  15.     # 执行命令,获取执行结果
  16.     result = subprocess.run(cmd, stderr=subprocess.PIPE, text=True, encoding='utf-8', errors='ignore')
  17.     # 将结果按行分割
  18.     lines = result.stderr.split('\n')
  19.     # 遍历每一行
  20.     for line in lines:
  21.         # 如果行中包含"bitrate"
  22.         if "bitrate" in line:
  23.             # 将行按空格分割,得到每个部分
  24.             bitrate_info = line.split(' ')
  25.             # 遍历每个部分
  26.             for i, info in enumerate(bitrate_info):
  27.                 # 如果部分是"bitrate:"
  28.                 if info == "bitrate:":
  29.                     # 返回下一个部分,即比特率值,加上"k"作为单位
  30.                     return bitrate_info[i + 1] + "k"  # 假设比特率单位为kbps
  31.     # 如果没有找到"bitrate:",则返回默认比特率"128k"
  32.     return "128k"  # 默认比特率
  33. def get_codec(audio_file):
  34.     # 使用 ffmpeg 获取音频文件的信息
  35.     cmd = [ffmpeg_path, '-i', audio_file]
  36.     result = subprocess.run(cmd, stderr=subprocess.PIPE, text=True, encoding='utf-8', errors='ignore')
  37.     
  38.     # 从输出中解析编解码器信息
  39.     lines = result.stderr.split('\n')
  40.     for line in lines:
  41.         if 'Stream #0:0' in line and 'Audio' in line:
  42.             codec_index = line.find('Audio: ')
  43.             if codec_index != -1:
  44.                 codec_info = line[codec_index + len('Audio: '):].split(',')[0].split()[0]
  45.                 return codec_info.strip()
  46.     
  47.     return None
  48. def swap_and_export_with_ffmpeg(input_file, output_file, bitrate, codec):
  49.     # 构建ffmpeg命令,用于交换声道并设置比特率
  50.     cmd = [
  51.         ffmpeg_path,  # 调用ffmpeg
  52.         '-i', input_file,  # 指定输入文件
  53.         '-acodec', codec,  # 指定音频编解码器
  54.         '-ac', '2',  # 确保输出为双声道
  55.         '-map_channel', '0.0.1', '-map_channel', '0.0.0',  # 交换声道
  56.         '-b:a', bitrate,  # 设置音频比特率
  57.         output_file  # 指定输出文件
  58.     ]
  59.     # 执行命令
  60.     subprocess.run(cmd, check=True)
  61. # 遍历当前目录下的所有文件
  62. for filename in os.listdir('.'):
  63.     # 如果文件是支持的音频格式
  64.     if filename.split('.')[-1] in supported_formats:
  65.         # 获取文件的比特率
  66.         bitrate = get_bitrate(filename)
  67.         # 获取文件的编解码器
  68.         codec = get_codec(filename)
  69.         # 使用ffmpeg交换声道并导出
  70.         swap_and_export_with_ffmpeg(filename, '左右反转_' + filename, bitrate, codec)


然后为了能在手机上也能愉快的转换,我顺便研究出了在安卓上处理的办法,但并不是特别推荐大家在手机上转(过程稍显复杂,不如pc端来的无脑),如果只是为了听而不是为了收藏转换后的音声就没必要搞的太复杂。其大致效果如下:




这俩办法我一并打包分享出来了,也专门录了演示视频,希望能给遇到类似困扰的坛友们一些帮助。

困了,睡了。。。
此帖售价 0 SP币,已有 27 人购买
若发现会员采用欺骗的方法获取财富,请立刻举报,我们会对会员处以2-N倍的罚金,严重者封掉ID!

none.gif

赏金猎人sg

非常感谢,祝大佬永远敏感 ୧⍢⃝୨

1637363.jpg

Fargo

图片:
PotPlayer 播放器可以设置互换声音啊,https://www.jb51.net/softjc/921148.html

乱码

B3F  2024-04-08 02:00
      

海绵体宝宝


none.gif

e4bc0177

手机有软件、电脑有播放器 都可以对转声道啊?

再不方便的播放器不也比转换文件方便多了

而且吧 如果你有foobar这种直接点几下就完成对调+输出了 哪用自己写一个

五月和弦


1368264.png

KvoRic

B7F  2024-04-13 15:20
(QaQ)
好好好,感谢技术贴

阿尔索斯


a6.gif

丸子超爱吃团子

确实有用

none.gif

ll

居然还可以这么玩

三夜

B11F  2024-04-18 13:34
          

881410.jpg

碎风天涯

B12F  2024-04-24 03:21
(天涯城里一抹风。)

回 2楼(Fargo) 的帖子

老哥为啥我点了也没效果啊,是要和声音输出轨道等设置联动吗 我选了声道互换重新打开文件也没效果

8.gif

Rivers77

B13F  2024-04-24 03:33
(诸君……我喜欢肛肛乐。)
能用播放器就用播放器,如果播放器不支持建议换一个播放器
一行ffmpeg就能解决的事情怎么还写了个py脚本,只要 -c:a copy就可以了,不需要自己指定编码和码率

greg


A3EZatGHlB4J5ro.png

Neko

B15F  2024-04-24 06:05
(自购贴均为原档)
楼主这个确实没用的步骤太多了,gpt写的?

1308351.png

浮霄

B16F  2024-04-24 21:56
(音声当然得笑着去听啦 >-<  愿你永葆那份欢愉)

回 15楼(Neko) 的帖子

确实,在它那个基础上改掉bug直接用的,能完成功能就行,我也懒得多改了
实践下来确实直接用ffmpeg命令行更快,但打包好了双击更无脑简单。

1308351.png

浮霄

B17F  2024-04-24 22:01
(音声当然得笑着去听啦 >-<  愿你永葆那份欢愉)

回 13楼(Rivers77) 的帖子

这不是为了让没装ffmpeg的兄弟们用着方便才搞成脚本打包了嘛
至于编码器和码率,实操的时候发现必须要专门指定,用copy也不好使(也可能是因为我菜吧233),不然很容易出现ffmpeg找不到编码器或者默认编码器和实际音频的编码器不一致的情况,导致声道交换后的音频质量下降。