我正在尝试以尽可能最佳的质量保存来自 Verizon Fios 手机的语音邮件。语音信箱消息可用在线的,但仅用于播放(基于Java的播放器),不保存。官方不支持如何将原始数字语音消息保存为来自 Fios 数字语音服务的文件(没有付费服务,没有任何内容,没有理由)。
我唯一的想法是在传输到声卡的过程中记录来自播放器的数字数据。我尝试使用循环设备进行 Linux ALSA 配置。
# cat /etc/asound.conf
# default device
pcm.!default {
type plug
slave.pcm "loop"
}
# output device
pcm.loopout {
type dmix
ipc_key 328211
slave.pcm "hw:Loopback,0,0"
}
# input device
pcm.loopin {
type dsnoop
ipc_key 686592
slave.pcm "hw:Loopback,1,0"
}
# duplex plug device
pcm.loop {
type plug
slave {
pcm {
type asym
playback.pcm "loopout"
capture.pcm "loopin"
}
}
}
这似乎可以工作并记录音频,例如,当在 Youtube 上播放某些内容时,音频输出会转到循环设备(默认音频输出),我可以捕获它(不确定它到底是如何工作的,我测试了 44.1kHz 和 48 Khz) )
arecord -f cd -D loop | aplay -f cd -D hw:0,0
arecord -f dat -D loop | aplay -f dat -D hw:0,0
但是当我尝试捕获 Verizon Java 音频播放器输出时,它是乱码,并且长度似乎不匹配。我怀疑它可能是 8 kHz 的单声道,我尝试了不同的方法,改变频率和格式,但没有任何帮助。
您知道这里出了什么问题以及如何记录消息吗?问题出在ALSA配置上吗?或者可能是内核问题? (我使用的是 3.4.88)。任何想法都会非常受欢迎。
答案1
有趣的问题,很久以前,我正在考虑通过一些虚拟音频和视频驱动程序来简单记录数字音频和视频,但从未实现。
我使用了您的配置文件,并且遇到了与您描述的完全相同的问题。 (我确实从 ALSA 中删除了 OSS 兼容性驱动程序,测试了不同的内核 - 似乎并不重要,并使用了 Debian Wheezy)
$ alsaplayer -d front audio.mp3
$ mplayer -vo null -ao alsa:device=front video.mp4
AO: [alsa] 44100Hz 2ch s16le (2 bytes per sample)
$ mplayer -ao alsa:device=front audio.mp3
AO: [alsa] 44100Hz 2ch s16le (2 bytes per sample)
以上命令对扬声器都播放正常
$ arecord -f cd -D loop | aplay -f cd -D front
Recording WAVE 'stdin' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo
Playing WAVE 'stdin' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo
现在从循环录音并播放到前面
$ alsaplayer audio.mp3
$ alsaplayer -d loop audio.mp3
$ mplayer -vo null video.mp4
$ mplayer -vo null -ao alsa:device=loop video.mp4
AO: [alsa] 48000Hz 2ch s16le (2 bytes per sample)
$ mplayer -ao alsa:device=loop audio.mp3
AO: [alsa] 48000Hz 2ch floatle (4 bytes per sample)
所有发送音频到循环并播放到扬声器都正常
$ mplayer audio.mp3
AO: [alsa] 48000Hz 2ch floatle (4 bytes per sample)
但这里声音被破坏了——非常扭曲!只是在默认设备上播放。通过循环指定的播放有效!
在尝试了各种更改之后,我测试了对 asound.conf 的修改
pcm.!default {
type plug
slave.pcm "loopout"
}
它解决了问题!当默认设备为环路时,它可以工作。尝试arecord -f cd -D loopin | aplay -f cd -D front
没有任何效果。不确定循环如何工作,但这能够捕获音频。还是 ALSA 中的错误?你使用的是 Debian 吗?对你起作用吗?
解决问题的其他建议的注释:
要转储网络流:我假设如果应用程序不希望您保存数据,则传输将被加密(https ???)。如果玩家没有检查服务器证书,如何捕获数据?您最喜欢的快速简单的方法是什么,如何成为中间人并捕获流?
Pulseaudio:如何让它在 Debian Wheezy 上运行?维基百科说它有效。它没。
/etc/init.d/pulseaudio start
[warn] PulseAudio configured for per-user sessions ... (warning).
我该如何解决发生的问题? (工具、诊断?)
Jack:我没有找到任何如何安装Jack的简单说明。看起来相当复杂。是否假设 Pulseaudio 正在运行?文档很混乱。您是否有一个快速入门的链接(如何安装和测试以确保其正常工作?)
您是否认为大多数音频应用程序(如 Fios Voicemail Java 播放器)能够播放 Pulseaudio 或 Jack 并且不能将音频发送到 ALSA?
答案2
您还记得“modprobe snd-aloop”吗?我已经尝试过,它对我来说适用于 youtube、pandora、tunein、vonage 和上的 asound.conf这个java播放器。可能是 Fios 特有的东西,但我没有 Fios 来测试。您能找到另一个也导致该问题的公开网站吗?
另外,尝试录制到文件,然后播放:
arecord -f cd -D loop > recording.wav
aplay -f cd -D hw:0,0 recording.wav
答案3
最好的主意
首先,阅读你的问题我不会这样做。我会监听网络并尝试捕获流。它可能位于一个相当可预测的位置,可以通过简单的调用来编写脚本tshark
。但这是另一个问题了。
相对 ALSA 的改进
虽然你的方法是一种有效的方法,我不会使用 ALSA。ALSA 是一个硬件抽象层。我会使用 PulseAudio 中几乎随处可见的声音守护进程。这更有意义。创建一个空接收器。
$ pactl load-module module-null-sink sink_name=MySink
该命令将返回您的module id
.这对我们来说没有用。
现在只需设置环境变量即可PULSE_SINK
。 (上例中的sink_name是“MySink”)
export PULSE_SINK=MySink;
或者,启动一个程序PULSE_SINK=MySink
,空接收器将捕获流。
每当您想将其流式传输到文件时,只需运行:
parec -v -d MySink.monitor | opusenc --raw --downmix-mono --bitrate 64 - out.opus
低比特率作品是录制电话交谈的最佳选择。
脚注:
- 您可能还想修剪走出前后的沉默。
sox
为此添加到流中。看看man sox
,寻找vad
。 - 我们正在
--downmix-mono
立体声流上使用。您可能非常想尝试在第一步中将channels=1
参数发送到。module-null-sink
电话都是单声道的。
答案4
我强烈推荐使用 JACK。这是 JACK Audio Connection Kit 的递归缩写。它是专门为您正在做的事情量身定制的,将音频从一个软件(在您的例子中是 Java 播放工具)路由到另一个软件(录音软件)。它非常适合低延迟录制,我认为这可以帮助您获得所需的质量。
有了它,您可以轻松地将音频从计算机上的任何来源路由到许多不同的录音工具。事实上,有一个非常好的 GUI,名为QjackCtl。
这一页介绍如何将音频从浏览器(Flash 和可能的 Java 工具)路由到 Jack。如何完成此操作取决于您的系统。
例如:
修改您的~/.asoundrc
或~/asound.conf
:
pcm.rawjack {
type jack
playback_ports {
0 system:playback_1
1 system:playback_2
}
capture_ports {
0 system:capture_1
1 system:capture_2
}
}
pcm.jack {
type plug
slave { pcm "rawjack" }
hint {
description "JACK Audio Connection Kit"
}
}
那么你应该能够使用
arecord -D pcm.jack <file>