Xamarin.iOS音频流无法工作,事件未被触发



所以,我的问题是,我试图用AudioFileStream和OutputAudioQueue类在Xamarin.iOS上流式传输音频。我已经为PacketDecoded和PropertyFound事件添加了处理程序,但它们没有被触发。怎么了?我的代码如下。。。

class AudioStreamer : IAudioStreamer // this is my dependency service interface
{
bool outputStarted;
AudioFileStream afs;
OutputAudioQueue oaq;
public void StartStreaming(string url)
{
afs = new AudioFileStream(AudioFileType.MP3);
// event handlers, these are never triggered
afs.PacketDecoded += OnPacketDecoded;
afs.PropertyFound += OnPropertyFound;
GetAudio(url);
}
void GetAudio(string url)
{
// HTTP
NSUrlSession session = NSUrlSession.FromConfiguration(
NSUrlSessionConfiguration.DefaultSessionConfiguration, 
new SessionDelegate(afs), 
NSOperationQueue.MainQueue);
var dataTask = session.CreateDataTask(new NSUrl(url));
dataTask.Resume();
}
// event handler - never executed
void OnPropertyFound(object sender, PropertyFoundEventArgs e)
{
if(e.Property == AudioFileStreamProperty.ReadyToProducePackets)
{
oaq = new OutputAudioQueue(afs.StreamBasicDescription);
oaq.BufferCompleted += OnBufferCompleted;
}
}
// another event handler never executed
void OnPacketDecoded(object sender, PacketReceivedEventArgs e)
{
IntPtr outBuffer;
oaq.AllocateBuffer(e.Bytes, out outBuffer);
AudioQueue.FillAudioData(outBuffer, 0, e.InputData, 0, e.Bytes);
oaq.EnqueueBuffer(outBuffer, e.Bytes, e.PacketDescriptions);
// start playing if not already
if(!outputStarted)
{
var status = oaq.Start();
if (status != AudioQueueStatus.Ok)
System.Diagnostics.Debug.WriteLine("Could not start audio queue");
outputStarted = true;
}
}
void OnBufferCompleted(object sender, BufferCompletedEventArgs e)
{
oaq.FreeBuffer(e.IntPtrBuffer);
}
}
// instantiated in GetAudio()
class SessionDelegate : NSUrlSessionDataDelegate
{
readonly AudioFileStream afs;
public SessionDelegate(AudioFileStream afs)
{
this.afs = afs;
}
// this is, too, never executed
public override void DidReceiveData(NSUrlSession session, NSUrlSessionDataTask dataTask, NSData data)
{
afs.ParseBytes((int)data.Length, data.Bytes, false);
}
}

顺便说一句,我大部分时间都是从这个屏幕截图中复制代码的。

您的代码看起来是正确的。。。

1) 我在您的源代码中看到了"http://"注释。您是否在不添加ATS异常的情况下从http://源进行流式传输?如果是这样,则dataTask.Resume();是"静默代码故障",因此不会调用任何代理/事件,iOS会记录它。

检查输出日志中是否有类似的内容:

StreamingAudio[13602:591658] App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.

使用https://源,但如果必须完全关闭ATS进行测试:

<key>NSAppTransportSecurity</key>  
<dict>  
<key>NSAllowsArbitraryLoads</key><true/>  
</dict>

注意:搜索iOS ATS以获取更多信息或详细信息,以便只允许来自您将要流式传输的服务器的非安全http://,但iOS的未来仅为https://,因此请开始准备…;-)

2) 如果提供给NSUrlSession的URL源产生一个连接被拒绝,这是一个无声的失败,并且没有关于它的日志记录,当然也没有调用您的委托/事件。。。预先测试您的流媒体web服务是否处于活动状态,请尝试使用curlwget等来测试流。。。

3) 我看到了你的流媒体mp3,所以你应该可以,但请记住,格式有数百种变体,iOS不会全部流媒体/播放它们,所以尝试通过不同的工具集编码的不同mp3,只是为了仔细检查。。。

最新更新