0

「initWithUrl:」メソッドで AVPlayerItem を初期化しています。

問題は、初期化が中断されたときです(接続が失われたなど)

以下があるとしましょう:

self.avPlayerItem = [[AVPlayerItem alloc] initWithUrl:url];

1. 何をすべきか? その間接続が失われると、avPlayerItem のインスタンスはどうなりますか? 初期化が成功したかどうかを識別するために実装するプロトコルはありますか?

2. 私が気づいたことは、初期化が中断されると、次の avPlayerItem の「成功した」初期化にトラックがまったくないことです (以前に中断が行われなかった場合に存在します)。アプリを閉じて、もう一度開きます。

4

2 に答える 2

1

インターネット接続に依存するコードを扱うときは、何か問題が発生したときに作動するフェイルセーフがあることを確認する必要があります。

何をすべきですか?

1) インターネット接続に依存するすべてのコードをバックグラウンド スレッドで実行します。UI をブロックしたくありません。

2) 可能であれば、使用する前にダウンロードしたファイルを確認してください。

これにはさまざまな方法がありますが、私の頭の上から、NSURLConnectionまたは同様の API を使用してファイルを一時フォルダーにダウンロードすると思います。背景スレッドで。

ダウンロードしたらAVAsset、一時 URL を使用して初期化します。ファイルが正常にダウンロードされたことを確認するのに役立つAVAssetようないくつかの優れたプロパティがあります。playable(NSURLConnectionDelegateダウンロード中にエラーが発生した場合に通知するメソッドもあります。)

あなたがここまで持っているなら、あなたはAVPlayerItemあなたAVAssetと離れて行くことができます. ダウンロードしたコンテンツを保持していない場合は、ある時点で一時フォルダーのコンテンツを消去することを忘れないでください。

メイン スレッドでファイルを再生したいが、他のすべての読み込みとチェックはおそらくバックグラウンド スレッドで行うのが最適であることを覚えておいてください。あなたは間違いなくNSURLConnectionバックグラウンドスレッドから使​​用したい.

于 2015-09-16T22:55:47.153 に答える
0

最初に AVPlayerItem を NSPurgeableData オブジェクトに格納し、そこから再生します。データオブジェクトを NSCache オブジェクトに保存して、再生後または接続が切断されたときにオブジェクトをメモリから自動的に削除し、以前の AVPlayerItem が新しいものに置き換えられます (これらすべては、あなたが説明する特定の問題)。開始するためのコードを次に示します。

void (^cachePlayerItem)(AVPlayerItem *, NSCache *, NSString *) = ^(AVPlayerItem *playerItem, NSCache *cache, NSString *key) {
    NSURL *fileURL = [(AVURLAsset *)playerItem.asset URL];
    NSPurgeableData *data = [NSPurgeableData dataWithContentsOfURL:fileURL];
    [data beginContentAccess];
    [cache setObject:data forKey:key];
    [data endContentAccess];
    [data discardContentIfPossible];
};

このブロックを実装ファイルの任意の場所に配置し、ヘッダー ファイルで次のように定義します。

typedef void (^cachePlayerItemBlock)(AVPlayerItem *, NSCache *, NSString *);

メソッド内で次のように呼び出します。

cachePlayerItem(playerItem, playerItems, phAsset.localIdentifier);

一方、playerItem は AVPlayerItem であり、playerItems は NSCache キャッシュであり、AVPlayerItem を取得しているアセットの種類に応じて、それに固有の何らかの識別子 (または上記の例では関連するアセット) です。

ちなみに、それに応じて AppDelegate でキャッシュを設定しました。

- (NSCache *)thumbnailCache {
    __block NSCache *t = self->_thumbnailCache;
    if (!t) {
        t = [[NSCache alloc] init];
        [t setName:@"Thumbnail Cache"];
        [t setEvictsObjectsWithDiscardedContent:TRUE];
        [t setCountLimit:self.assetsFetchResults.count];
        self->_thumbnailCache = t;
    }
    return t;
}

これにより、キャッシュへのグローバル アクセスだけでなく、キャッシュの 1 つのインスタンスも保証されます。これは、サイズが大きくなる可能性があるため、AVPlayerItem をキャッシュする場合に特に重要です。

AppDelegate でグローバルにアクセス可能なキャッシュを作成するには、これらをヘッダー ファイルと実装ファイルにそれぞれ追加します。

+ (AppDelegate *)sharedAppDelegate;

...と:

+ (AppDelegate *)sharedAppDelegate
{
    return (AppDelegate *)[[UIApplication sharedApplication] delegate];
}

他のクラス ファイルでキャッシュを参照するには、AppDelegate ヘッダー ファイルをインポートし、必要に応じて、AppDelegate の sharedApplication メソッドへのショートカットを作成します。

#import "AppDelegate.h"

#define AppDelegate ((AppDelegate *)[[UIApplication sharedApplication] delegate])

そうすることで、キャッシュは次の方法で参照できます...:

AppDelegate.thumbnailCache

...それ以外の:

AppDelegate.sharedAppDelegate.thumbnailCache
于 2016-10-22T11:54:59.717 に答える