

Objective-Cを使って、iOSアプリを作成しています。  
ネットワーク上のMP3ファイルを読み込んで、音声を再生しようと思い、  
AVFoundationのAVPlayerとAVPlayerItemというクラスを使って、  
[AVPlayerItem playerItemWithURL:url]のように、  
インターネット上のURLを指定して音声の再生を行っています。

AVFoundationプログラミングガイド(<https://developer.apple.com/jp/documentation/AVFoundationPG.pdf>)  
に従って、AVPlayerのstatusのキー値を監視し、  
AVPlayerStatusReadyToPlay(再生の準備が整った)になったら再生を開始し、  
AVPlayerStatusFailed(再生に失敗した)になったらエラーを表示しています。

URLにアクセスできない場合などは、即座にstatusがAVPlayerStatusFailedになりますが、  
タイムアウト時には、約60〜90秒ぐらいたってから、statusの値が変化し、  
AVPlayerのerrorに"NSURLErrorDomain"でタイムアウトエラーの情報が設定される動きになっています。

このタイムアウト時間を任意の値に設定したいと思っているのですが、  
AVPlayer関連のクラスにそのような情報を設定するプロパティが見当たらず困っています。  
なんとかして設定する方法はないものでしょうか？


CC BY-SA 3.0
2016-01-24T00:38:52.477
21243
2016-04-23T04:02:18.223
14120
question
ios objective-c
AVPlayerにタイムアウト時間を設定したい


改めてリファレンスを見てみましたが、タイムアウトを指定するようなプロパティは確かに見当たりません。このような場合には、自前でタイムアウト処理を実装しないと仕方ないのではないかと思います。

AVFoundationプログラミングガイドに従ってコードを書いているのであれば、キー値監視でstatusの変化を監視するコードを書いていると思いますが、そこにタイムアウト監視の処理を追加します。

[code]

    #define TIMEOUT_SEC (10)
        _player = [AVPlayer playerWithURL:url];
        [_player addObserver:self forKeyPath:@"status" options:0
                context:&PlayerStatusContext];
        _timeoutTimer = [NSTimer scheduledTimerWithTimeInterval:TIMEOUT_SEC target:self
           selector:@selector(playerTimeout:) userInfo:nil repeats:NO];
    
[/code]

後は指定したタイムアウト処理の中で必要な処理を記載してください。

[code]

    - (void)playerTimeout:(NSTimer *)timer {
        if( _player.status != AVPlayerStatusReadyToPlay ) {
            [_player removeObserver:self forKeyPath:@"status" context:&PlayerStatusContext];
            //キャンセル処理
        }
        [timer invalidate];
    }
    
[/code]

普通に再生できるようになった場合には、タイマーのinvalidateも必要ですね。

[code]

    - (void)observeValueForKeyPath:(NSString *)keyPath
     ofObject:(id)object
     change:(NSDictionary *)change context:(void *)context
    {
        if( context == &PlayerStatusContext ) {
            [_timeoutTimer invalidate];
            //再生開始処理
        //} else if(...) {
        } else {
            [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
        }
    }
    
[/code]

実際に動作確認できるまでのコードを書く暇はなかったので、若干の修正が必要かもしれませんが、おおよそこのやり方でタイムアウト処理が実装できるはずです。


CC BY-SA 3.0
2016-01-24T01:22:10.157
21244
2016-01-24T01:40:36.540
2016-01-24T01:40:36.540
13972
13972
21243
answer