7

AVPlayer を使用してオーディオをストリーミングしています。それはうまくいっています。しかし今、典型的な音楽プレーヤーのように、オーディオを前後に移動するスライダーを作成する必要があります。seekToTimeローカルオーディオファイルでうまく機能する機能を使用しました。しかし、Web URL から曲をストリーミングすると、大きな範囲でスライダーを進めると、機能がオーディオを停止します。

私の推測では、曲がダウンロードされており、スライダーを大きな範囲で前方に動かすと、システムがその時間の曲データ パケットをダウンロードしていない可能性があるため、プレーヤーが停止します。

ボタンを押して曲をストリーミングするとしますが、0 秒から 100 秒ですぐにスライダーを動かします。この場合、システムが機能しておらず、プレーヤーが停止します。その時間のデータ パケットが不足しているためです。

この問題を克服する方法を知っている人はいますか、それとも他のアプローチがありますか。開発にはSWIFTを使用しています。迅速に機能する場合は、どのライブラリも使用するつもりです。これは私の機能です:

func forward () {
    timeGap = slider.value
    let preferredTimeScale : Int32 = 1
    let targetTime : CMTime = CMTimeMake(timeGap, preferredTimeScale)

    player.seekToTime(targetTime, toleranceBefore: kCMTimeZero, toleranceAfter: kCMTimeZero)

}

前もって感謝します。

4

1 に答える 1

9

この回答は、 https ://stackoverflow.com/a/7195954/765298 に大きく基づいています。これは単なるswiftへの翻訳であるため、すべてのクレジットはそこに記載する必要があります。

まだバッファリングされていない部分をはるかに前方にシークすると、プレーヤーが停止すると想定するのは正しいことです。問題は、データをバッファリングしますが、準備ができたときに自動的に開始されないことです。したがって、リンクされた回答を swift に言い換えると、次のようになります。

オブザーバーをセットアップするには:

player.currentItem?.addObserver(self, forKeyPath: "playbackBufferEmpty", options: .New, context: nil)
player.currentItem?.addObserver(self, forKeyPath: "playbackLikelyToKeepUp", options: .New, context: nil)

値を観察できるようにするには、渡さselfれた を から継承する必要があることに注意してくださいNSObject

そしてそれらを処理するには:

override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {

    guard keyPath != nil else { // a safety precaution
        super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context)
        return
    }

    switch keyPath! {
        case "playbackBufferEmpty" :
            if player.currentItem!.playbackBufferEmpty {
                print("no buffer")
                // do something here to inform the user that the file is buffering
            }

        case "playbackLikelyToKeepUp" :
            if player.currentItem!.playbackLikelyToKeepUp {
                self.player.play()
                // remove the buffering inidcator if you added it
            }
    }
}

また、現在再生中の利用可能な時間範囲に関する情報を取得することもできます(自分で作成していない場合はAVPlayerItem、経由でアクセスできます)。player.currentItemこれにより、ファイルのどの部分の準備ができているかをユーザーに示すことができます。

いつものように、ドキュメントでさらに読むことができます: AVPlayerItemAVPlayer

キー値監視 (KVO) の詳細については、こちらをご覧ください。

于 2015-11-27T12:23:06.497 に答える