2

この質問は Stack Overflow 全体にあることは知っていますが、それでも、それらのほとんどは古く、ここで質問する内容とは関係ありません。

だから私は と の配列を持っAVPlayerItemsていAVQueuePlayerます。最初に、配列アイテムを再生するように AVQueuePlayer を設定します。

func mediaPicker(mediaPicker: MPMediaPickerController!, didPickMediaItems mediaItemCollection: MPMediaItemCollection!) {

    mediaItems = mediaItemCollection.items

    for thisItem in mediaItems as [MPMediaItem] {

        var itemUrl = thisItem.valueForProperty(MPMediaItemPropertyAssetURL) as? NSURL
        var playerItem = AVPlayerItem(URL: itemUrl)
        mediaArray.append(playerItem)           

    }

    updateMetadata()

    audioPlayer = AVQueuePlayer(items: mediaArray)


    self.dismissViewControllerAnimated(true, completion: nil)

}

しかし、たとえば、ユーザーが新しいアイテムを追加したり、アイテムを削除したりすると、プレーヤーを更新しようとします (最初に設定したのと同じ方法) が、エラーが発生します。回避策、または解決策があるかどうかを知りたいです。これは、ユーザーが曲を削除する方法です。

func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
        if editingStyle == UITableViewCellEditingStyle.Delete{
            mediaArray.removeAtIndex(indexPath.row)
            tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
            audioPlayer = AVQueuePlayer(items: mediaArray) //here gives the error
        }
    }

私はこれで自殺しているので、誰かが私を助けてくれれば幸いです.

4

6 に答える 6

4

問題は、この行 (tableView:commitEditingStyle:forRowAtIndexPath: 内) でアイテムの配列を更新するときに、新しいプレーヤー オブジェクトを作成していることです。

audioPlayer = AVQueuePlayer(items: mediaArray)

これを行うと、プレーヤー アイテムはまだ元のプレーヤーに関連付けられているようです。適切に機能させるために、その行を削除できるはずです。mediaArray にアイテムを挿入または削除するだけで、必要なことを行うことができます。新しいプレーヤーを作成する必要はありません。

于 2015-06-05T15:19:19.570 に答える
2

Appleのドキュメントから:

アイテムを追加する前に:

canInsertItem(_:afterItem:)

特定のプレーヤー アイテムをプレーヤーのキューに挿入できるかどうかを示すブール値を返します。

func canInsertItem(_ item: AVPlayerItem!, afterItem afterItem: AVPlayerItem!) -> Bool

アイテムの追加:

insertItem(_:afterItem:)

指定されたプレーヤー アイテムをキュー内の指定されたアイテムの後に配置します。

 func insertItem(_ item: AVPlayerItem!, afterItem afterItem: AVPlayerItem!)

アイテムの削除:

removeItem(_:)

指定されたプレーヤー アイテムをキューから削除します。

func removeItem(_ item: AVPlayerItem!)

于 2015-06-05T03:11:12.033 に答える
2

この問題を解決した方法は、AVAssetオブジェクトへの参照を配列に保持し、それを( init が受け入れる型)mapにペディングすることでした。[AVPlayerItem]AVQUeuePlayer

詳しく説明すると、一時停止できるオーディオ レコーダー ( github のコードAVQueuePlayer) を作成する必要があったため、 を使用しましたが、OP と同じ問題に遭遇しました。唯一のクリーンな解決策は、このプレーヤー オブジェクトを新しい配列で再作成することです.

Swift 4.1の関連コード:

class RecordViewController: UIViewController {

    var audioRecorder: AVAudioRecorder?

    var audioChunks = [AVURLAsset]()
    var queuePlayer:  AVQueuePlayer?

// irrelevant code omitted

    func stopRecorder() {
        self.audioRecorder?.stop()
        let assetURL  = self.audioRecorder!.url

        self.audioRecorder = nil

        let asset = AVURLAsset(url: assetURL)
        self.audioChunks.append(asset)

        let assetKeys = ["playable"]
        let playerItems = self.audioChunks.map {
            AVPlayerItem(asset: $0, automaticallyLoadedAssetKeys: assetKeys)
        }

        self.queuePlayer = AVQueuePlayer(items: playerItems)
        self.queuePlayer?.actionAtItemEnd = .advance
    }

    func startPlayer() {
        self.queuePlayer?.play()
    }

    func stopPlayer() {
        self.queuePlayer?.pause()
        self.queuePlayer = nil
    }
}

(最終的に、AVAssetExportSessionはオーディオのチャンクをつなぎ合わせるために使用されるAVAssetため、 s の代わりにs を保存することAVPlayerItemは、最終的にはさらに有益でした。)

于 2018-04-20T00:12:41.920 に答える