You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Xamarin Forms iOS中AVAudioPlayer抛出‘player did not see an IO cycle’异常

Xamarin Forms iOS音频播放器异常:player did not see an IO cycle

我在Xamarin Forms iOS平台开发音频播放器,这个问题已经困扰我一个多月了。播放器会将securityscoped URL保存至沙箱内的自定义库中(URL通过UIDocumentPickerViewController选择,以MinimalBookmark形式保存为NSData)。

用户选择书签时,应用执行以下步骤:

  • 从NSData中恢复URL
  • 开始访问securityscoped资源
  • 将文件复制到沙箱内的临时文件
  • 从临时文件创建AVAudioFile
  • 定位到文件的第2秒位置
  • 尝试播放,此时抛出异常

异常出现的特殊规律:用户从App Store下载应用后,最初几小时运行正常,但1-2小时后会持续抛出该异常,唯一恢复播放的方法是重新从App Store安装应用。

补充说明:我了解到有文章指出该异常可能在设备切换音频路由(如蓝牙音箱)时出现,但我的用户始终使用iPhone内置扬声器,因此排除该情况。

AVAudioEngine engine;
AVAudioPlayerNode player;
AVAudioFile file;


void Play()   
{    
    AVAudioFormat format = null;
    bool restarted = false;
    NSUrl url = null;
    NSError err;
    string tempFile;

    try
    {
        url = UrlMgr.GetAudioNSUrl();

        if (url == null)
            return;

        if (UrlMgr.IsAudioUriSecurityScoped)
        {
            //this is fine, getting access never fails
            if (!url.StartAccessingSecurityScopedResource())
            {
                AppCenterMgr.TrackWarning("Play security error", true, "message");
                return;
            }
        }

        //get tempaudiopath copies the security scoped file into internal storage which 
        //is in the app sandbox. This never fails
        tempFile = GetTempAudioPath(url);
        file = new AVAudioFile(tempFile, out err);

        if (UrlMgr.IsAudioUriSecurityScoped)
            url.StopAccessingSecurityScopedResource();


        //these always give legitimate values indicating the 
        //AVAudioFile has been created successfully
        _lengthSamples = file.Length;
        format = file.ProcessingFormat;
        _sampleRate = format.SampleRate;

        //put this here just in case engine has been stopped unexpectedly
        //but this is never a problem, engine is always running
        if (!engine.Running)
            restarted = RestartEngine(true);

        SetAudioPlaybackPosition();

        //this works for a few hours, but after that fails repeatedly and 
        //thereafter never works again
        player.Play();

        //never reaches here
        timer.Start();

    }
    catch (Exception e)
    {
        //Objective-C exception thrown. Name: com.apple.coreaudio.avfaudio Reason: player did not see an IO cycle.
        AppCenterMgr.TrackError(e, "msg", e.Message, 
                                   "enginerunning", engine.Running, 
                                   "restarted", restarted,           //false
                                   "audiofilelen", file.Length);     //8691712 -> file seems to be valid

        if (UrlMgr.IsAudioUriSecurityScoped)
            url?.StopAccessingSecurityScopedResource();

    }
}

uint remainingSamples;
long startSample;
void SetAudioPlaybackPosition()
{
    //start playback 2 seconds in
    int time = 2000;

    startSample = (long)(time * _sampleRate / 1000);
    remainingSamples = (uint)(_lengthSamples - startSample);
    player.ScheduleSegment(file, startSample, remainingSamples, null, AVAudioPlayerNodeCompletionCallbackType.PlayedBack, OnEndReached);


}

public NSUrl GetTempAudioPath(NSUrl url)
{
    string path = null;
    FileInfo fi;

    using (FileStream s = new FileStream(url.Path.ToString(), FileMode.Open))
    {
        path = Path.Combine(FileSystem.AppDataDirectory, "temp.mp3");

        using (FileStream fileStream = File.Create(path))
        {
            s.Seek(0, SeekOrigin.Begin);
            s.CopyTo(fileStream);
        }

    }

    //check -> this never fails
    fi = new FileInfo(path);
    if (fi.Length < 100)
    {
        AppCenterMgr.TrackWarning("Small Audio File", false, "path", path, "len", fi.Length);
    }


    return new NSUrl(path);
}

MS App Center 崩溃日志

Foundation.MonoTouchException: Objective-C exception thrown. Name: com.apple.coreaudio.avfaudio Reason: player did not see an IO cycle. Native stack trace: 0 CoreFoundation 0x00000001a364cf2c 00E76A98-210C-3CB5-930B-F236807FF24C + 540460 1 libobjc.A.dylib 0x000000019b552018 objc_exception_throw + 60 2 CoreFoundation 0x00000001a374b66c 00E76A98-210C-3CB5-930B-F236807FF24C + 1582700 3 AVFAudio 0x00000001bd1c4198 A161186B-22A2-3A88-B6AE-3A022764AE54 + 16792 4 AVFAudio 0x00000001bd2b23a0 A161186B-22A2-3A88-B6AE-3A022764AE54 + 992160 5 AVFAudio 0x00000001bd1c4608 A161186B-22A2-3A88-B6AE-3A022764AE54 + 17928 6 AVFAudio 0x00000001bd2aea84 A161186B-22A2-3A88-B6AE-3A022764AE54 + 977540 7 Xamarin.Sdk 0x000000010ab95510 wrapper_managed_to_native_ObjCRuntime_Messaging_objc_msgSend_intptr_intptr_6 + 128 8 Xamarin.Sdk 0x000000010ab25964 AVFoundation_AVAudioPlayerNode_Play + 36 9 MyApp.iOS 0x00000001029e0324 sqlite3_sourceid + 4210204 10 MyApp.iOS 0x0000000102a724c0 sqlite3_sourceid + 4808632 11 MyApp.iOS 0x00000001029df924 sqlite3_sourceid + 4207644 12 MyApp.iOS 0x0000000102895598 sqlite3_sourceid + 2855056 13 MyApp.iOS 0x0000000102a623f8 sqlite3_sourceid + 4742896 14 MyApp.iOS 0x0000000102894fa4 sqlite3_sourceid + 2853532 15 MyApp.iOS 0x00000001028868b0 sqlite3_sourceid + 2794408 16 Xamarin.Sdk 0x000000010aaaded4 Foundation_NSAsyncActionDispatcher_Apply + 36 17 Xamarin.Sdk 0x000000010a1b49a0 wrapper_runtime_invoke_object_runtime_invoke_dynamic_intptr_intptr_intptr_intptr + 272 18 Mono 0x000000010720fc4c mono_jit_runtime_invoke + 1136 19 Mono 0x00000001072ca41c mono_runtime_invoke_checked + 148 20 Mono 0x00000001072cdc5c mono_runtime_invoke + 144 21 MyApp.iOS 0x00000001027b9f2c sqlite3_sourceid + 1956388 22 MyApp.iOS 0x00000001027bede0 sqlite3_sourceid + 1976536 23 Foundation 0x00000001a2529aa4 3D3A12E3-F5E9-361F-B00A-4A5E8861AA55 + 740004 24 CoreFoundation 0x00000001a361f834 00E76A98-210C-3CB5-930B-F236807FF24C + 354356 25 CoreFoundation 0x00000001a361f7c8 00E76A98-210C-3CB5-930B-F236807FF24C + 354248 26 CoreFoundation 0x00000001a361d298 00E76A98-210C-3CB5-930B-F236807FF24C + 344728 27 CoreFoundation 0x00000001a361c484 00E76A98-210C-3CB5-930B-F236807FF24C + 341124 28 CoreFoundation 0x00000001a361bcd8 CFRunLoopRunSpecific + 608 29 GraphicsServices 0x00000001e84cc1a8 GSEventRunModal + 164 30 UIKitCore 0x00000001a5c5490c 1741FA37-4E53-371E-8DAE-D611AAB0043D + 4237580 31 UIKitCore 0x00000001a5d089d0 UIApplicationMain + 340 32 Xamarin 0x00000001066274d8 xamarin_UIApplicationMain + 24 33 Xamarin.Sdk 0x000000010ab90ac8 wrapper_managed_to_native_UIKit_UIApplication_xamarin_UIApplicationMain_int_intptr_intptr_intptr_intptr_ + 152 34 Xamarin.Sdk 0x000000010aae07bc UIKit_UIApplication_UIApplicationMain_int_string___intptr_intptr + 76 35 Xamarin.Sdk 0x000000010aae0960 UIKit_UIApplication_Main_string___System_Type_System_Type + 224 36 MyApp.iOS 0x00000001029eb054 sqlite3_sourceid + 4254540 37 Xamarin.Sdk 0x000000010a1b49a0 wrapper_runtime_invoke_object_runtime_invoke_dynamic_intptr_intptr_intptr_intptr + 272 38 Mono 0x000000010720fc4c mono_jit_runtime_invoke + 1136 39 Mono 0x00000001072ca41c mono_runtime_invoke_checked + 148 40 Mono 0x00000001072d0724 mono_runtime_exec_main_checked + 128 41 Mono 0x00000001071ed308 mono_jit_exec + 376 42 Xamarin 0x000000010663ab84 xamarin_main + 1064 43 MyApp.iOS 0x00000001027f65bc sqlite3_sourceid + 2203828 44 dyld 0x00000001c6ccde4c 71846EAC-EE65-3697-BF7D-790B6A07DCDB + 249420

内容的提问来源于stack exchange,提问作者jho

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 23:37:32