ios - Xamarin.iOS 音频流不起作用,未触发事件

标签 ios events audio xamarin 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);
    }
}

顺便说一句,我主要是从 this screencast 复制代码.

最佳答案

您的代码看起来正确...

1)我在您的来源中看到“http://”评论。您的流媒体是否来自 http://源而不添加 ATS 异常?如果是这样,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 的 future 是 https://只有这样开始准备... ;-)

2) 如果提供给 NSUrlSession 的 URL 源产生 连接被拒绝 ,这是一个无声的失败,并且没有关于它的日志记录,当然没有任何代表/事件被调用...预先测试您的流式 Web 服务是否处于事件状态,尝试使用 curl , wget等...测试流...

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

关于ios - Xamarin.iOS 音频流不起作用,未触发事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37470136/

相关文章:

audio - FFMPEG 音频规范化器 dynaudnorm 对 amix 没有影响

ios - UITextView 接收文本形式的听写,但文本在 textView.text 属性中为 nil

ios - 手动隐藏搜索栏 Controller

ios - 在模拟器中测试多任务 iOS 9 功能

c# - 区分用户交互引发的事件和我自己的代码

javascript - 动态创建的元素上的事件绑定(bind)?

ios - 如何在父 TapGestureRecognizer 之前触发 UIButton 目标事件

android - 覆盖通知声音Android

c# - SoundPlayer无法使用字符串

ios - 如何修复错误: Generic parameter 'T' could not be inferred