我正在尝试从颤振的字节流中播放音频。我已经使用了Just Audio包的例子从字节流读取,我仍然得到一个错误。错误是:
Playback error
E/ExoPlayerImplInternal(19173): com.google.android.exoplayer2.ExoPlaybackException: Source error
E/ExoPlayerImplInternal(19173): at com.google.android.exoplayer2.ExoPlayerImplInternal.handleIoException(ExoPlayerImplInternal.java:632)
E/ExoPlayerImplInternal(19173): at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:602)
E/ExoPlayerImplInternal(19173): at android.os.Handler.dispatchMessage(Handler.java:98)
E/ExoPlayerImplInternal(19173): at android.os.Looper.loop(Looper.java:154)
E/ExoPlayerImplInternal(19173): at android.os.HandlerThread.run(HandlerThread.java:61)
E/ExoPlayerImplInternal(19173): Caused by: com.google.android.exoplayer2.source.UnrecognizedInputFormatException: None of the available extractors (Mp3Extractor, FlvExtractor, FlacExtractor, WavExtractor, FragmentedMp4Extractor, Mp4Extractor, AmrExtractor, PsExtractor, OggExtractor, TsExtractor, MatroskaExtractor, AdtsExtractor, Ac3Extractor, Ac4Extractor, AviExtractor, JpegExtractor) could read the stream.
E/ExoPlayerImplInternal(19173): at com.google.android.exoplayer2.source.BundledExtractorsAdapter.init(BundledExtractorsAdapter.java:92)
E/ExoPlayerImplInternal(19173): at com.google.android.exoplayer2.source.ProgressiveMediaPeriod$ExtractingLoadable.load(ProgressiveMediaPeriod.java:1017)
E/ExoPlayerImplInternal(19173): at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:412)
E/ExoPlayerImplInternal(19173): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
E/ExoPlayerImplInternal(19173): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
E/ExoPlayerImplInternal(19173): at java.lang.Thread.run(Thread.java:762)
E/AudioPlayer(19173): TYPE_SOURCE: None of the available extractors (Mp3Extractor, FlvExtractor, FlacExtractor, WavExtractor, FragmentedMp4Extractor, Mp4Extractor, AmrExtractor, PsExtractor, OggExtractor, TsExtractor, MatroskaExtractor, AdtsExtractor, Ac3Extractor, Ac4Extractor, AviExtractor, JpegExtractor) could read the stream.
我可以看出输入格式有问题。然而,我只是不确定它是什么。下面是应该执行播放的代码:
void initAudio() async {
final server = await ServerSocket.bind(InternetAddress.anyIPv4, port);
final player = AudioPlayer();
final session = await AudioSession.instance;
await session.configure(const AudioSessionConfiguration.speech());
await session.setActive(true);
server.listen((socket) {
// event is a socket
socket.listen((Uint8List data) async {
print(data);
player.setAudioSource(MyCustomSource(data), preload: false);
player.play();
});
});
}
MyCustomSource
来自Just Audio pub.dev列表,它看起来像这样:
// Feed your own stream of bytes into the player
class MyCustomSource extends StreamAudioSource {
final List<int> bytes;
MyCustomSource(this.bytes);
@override
Future<StreamAudioResponse> request([int? start, int? end]) async {
start ??= 0;
end ??= bytes.length;
return StreamAudioResponse(
sourceLength: bytes.length,
contentLength: end - start,
offset: start,
stream: Stream.value(bytes.sublist(start, end)),
contentType: 'audio/mpeg',
);
}
}
我正试图通过套接字发送Stream<List<int>>
以通过互联网流式传输音频。下面是音频发送方:
void recordAudio() async {
print("recording and sampling");
final socket = await Socket.connect(a5atHome, port);
Stream<Uint8List>? stream = await MicStream.microphone(sampleRate: 44100);
socket.addStream(stream!);
StreamSubscription<List<int>> listener = stream.listen((samples) async {
print(samples);
});
}
我也不确定发送方是否有问题。我刚开始使用JustAudio,我不确定错误来自哪里。如有任何帮助,我将不胜感激。
编辑:顺便说一下,我使用mic_stream
pub.dev包以流的形式获取麦克风数据
终于想通了。感谢Ryan Heise为我指明了正确的方向。
MicStream
包以原始PCM格式记录音频数据,所以我需要找到一个可以以这种格式播放音频的包。从这个答案中,我发现有人正在寻找做完全相同的事情-基本上播放音频数据的List<int>
音频。
根据另一个答案,名为flutter_sound
的包可以为我做这件事。
发送方:
final socket = await Socket.connect(a5atHome, port);
Stream<Uint8List>? stream = await MicStream.microphone(
sampleRate: 44100, audioFormat: AudioFormat.ENCODING_PCM_16BIT);
await socket.addStream(stream!);
和需要修改的比赛方:
FlutterSoundPlayer player = FlutterSoundPlayer();
final server = await ServerSocket.bind(InternetAddress.anyIPv4, port);
final session = await AudioSession.instance;
await session.configure(const AudioSessionConfiguration.speech());
await session.setActive(true);
await player.openPlayer(enableVoiceProcessing: true);
server.listen((socket) async {
await player.startPlayerFromStream(
codec: Codec.pcm16, numChannels: 1, sampleRate: 44100);
socket.listen((Uint8List data) async {
player.foodSink!.add(FoodData(data));
});
});
MicStream
的ENCODING_PCM_16BIT
格式与flutter_sound
的Codec.pcm16
格式相同。格式匹配,声音播放!