3

現在、FairPlayストリーミングでオフラインストリーミングを実装しています。そのため、AVAssetDownloadTaskを使用してストリームをダウンロードしています。私は、ユーザーが開始するために開始し、ダウンロードのサイズに関するフィードバック与えたいダウンロードする前にAVAssetDownloadTaskのサイズを取得します。

は、あなたがこのストリームをダウンロードしてもよろしいですか?これは、ダウンロードするための2.4ギガバイトを取ると、あなたは、現在のスペースの14ギガバイトは、私がcountOfBytesReceivedcountOfBytesExpectedToReceiveのようなプロパティをチェックしましたが、これらは文句を言わないバック正しい値を与える

を残しています。

let headRequest = NSMutableURLRequest(URL: asset.streamURL) 
headRequest.HTTPMethod = "HEAD" 
let sizeTask = NSURLSession.sharedSession().dataTaskWithRequest(headRequest) { (data, response, error) in 
    print("Expected size is \(response?.expectedContentLength)") 
}.resume() 

は、最終サイズが3GBのサイズを出力します。

func URLSession(session: NSURLSession, assetDownloadTask: AVAssetDownloadTask, didLoadTimeRange timeRange: CMTimeRange, totalTimeRangesLoaded loadedTimeRanges: [NSValue], timeRangeExpectedToLoad: CMTimeRange) { 
    print("Downloaded \(convertFileSizeToMegabyte(Float(assetDownloadTask.countOfBytesReceived)))/\(convertFileSizeToMegabyte(Float(assetDownloadTask.countOfBytesExpectedToReceive))) MB") 
} 

しかし、これらはゼロに滞在:私は性質上ログインしてダウンロード中

は、私は、このAPIで働いていない0.0/0.0メガバイト

+0

この@Antoine – bnussey

答えて

0

をダウンロード個人的には、少なくとも私はHTTPライブストリーミングにはある程度精通しています。その知識によって、私はあなたが探している情報を得ることができない理由を知っていると思います。

HLSプロトコルは、固定長資産のストリーミングとストリーミングを処理するように設計されています。これは通常、約10秒のチャンクであるIIRCにメディアを分割し、特定のURLの再生リストファイルにそれらのチャンクのURLをリストすることによって行います。

プレイリストが変更されない場合は、プレイリストをダウンロードしてファイル数を計算し、最初のファイルの長さを取得し、ファイル数でそれを掛けます。近似は、最後のチャンクの取得を開始するときに正確な値に置き換えることができます。

ただし、プレイリストが変更されないという保証はありません。 HLSを使用すると、プレイリストは、最も古いセグメントを削除(または削除)し、最後に新しいセグメントを追加することで、10秒ごとに変更される可能性があります。このようにして、HLSは、終わりのない生放送のストリーミングをサポートする。この文脈において、サイズを有するダウンロードの概念は無意味である。

さらに悪いことに、2464はおそらくプレイリストファイルのサイズで、最初のアセットのサイズではなく、サブクラスのdidReceiveResponse:メソッドが動作しない限り何も伝えません。各セグメントの長さは、Content-Lengthヘッダーを読み取ることで取得できます。また、正常に動作しても、このAPIからセグメント数を取得することはできません(かなり近いはずですが、すべてのセグメントが正確に同じ長さになるという保証もありません)。

あなたが望む情報を取得することは、ライブ以外のアセットであっても、おそらくプレイリストを取得して自分で解析し、リストされたメディアセグメントURLごとに一連のHEADリクエストを実行する必要がありますその中に。

幸いにも、HLS仕様は一般に公開されている標準なので、そのパスを下ろす場合は、読めるRFCがあり、プレイリストファイルの構造について学ぶことができます。また、AFAIKでは、プレイリスト自体はDRMなどで暗号化されていないため、APIの実際の復号化部分は公開されていません(AFAIK)。

1

実際にHLSストリームは、マニフェストおよびトランスポートストリームと呼ばれるファイルの集合です。マニフェストは、通常、サブマニフェストのテキストリスト(それぞれが異なるビットレートに対応する)を含み、これらのサブマニフェストは、実際のムービーデータを含むトランスポートストリームのリストを含む。

あなたのコードでは、HLS URLをダウンロードすると、実際にはマスターマニフェストだけがダウンロードされます。これは、通常、数千バイトです。ストリーム全体をコピーする場合は、すべてのマニフェストを解析し、元のストリームのフォルダ構造を複製し、トランスポートセグメントも取得する必要があります(通常は10秒のセグメントになるため、数百これら)。マニフェストが絶対URLで指定されている場合は、URLを書き換える必要があります。

各ストリームのサイズを計算するには、ストリームの長さでビットレート(マスターマニフェストにリストされています)を掛けることができます。それはダウンロードのための十分な見積もりであるかもしれません。

ここで、より良い答えは、オフラインFairPlayのコンテキストでAVAssetDownloadTaskを使用しているため、AVAssetDownloadDelegateを実装することです。

URLSession:assetDownloadTask:didLoadTimeRange:totalTimeRangesLoaded:timeRangeExpectedToLoad:

ここだWWDC 2016 Session 504アクションで、このデリゲートを示した:そのプロトコルにおける方法の一つは、あなたが探しているの進行状況を示します。

FairPlayのオフライン再生に関する詳細はたくさんありますので、そのビデオを非常に慎重に検討することをお勧めします。

0

これは最終ダウンロードサイズを計算するためのC#/ Xamarinコードです。おそらく、iOS11でサポートされている新しいコーデックでは、不完全かもしれませんが、あなたはそのアイデアを得るべきです。

private static async Task<long> GetFullVideoBitrate(string manifestUrl) 
{ 
    string bandwidthPattern = "#EXT-X-STREAM-INF:.*(BANDWIDTH=(?<bitrate>\\d+)).*"; 
    string videoPattern = "^" + bandwidthPattern + "(RESOLUTION=(?<width>\\d+)x(?<height>\\d+)).*CODECS=\".*avc1.*\".*$"; 
    string audioPattern = "^(?!.*RESOLUTION)" + bandwidthPattern + "CODECS=\".*mp4a.*\".*$"; 

    HttpClient manifestClient = new HttpClient(); 
    Regex videoInfoRegex = new Regex(videoPattern, RegexOptions.Multiline); 
    Regex audioInfoRegex = new Regex(audioPattern, RegexOptions.Multiline); 
    string manifestData = await manifestClient.GetStringAsync(manifestUrl); 
    MatchCollection videoMatches = videoInfoRegex.Matches(manifestData); 
    MatchCollection audioMatches = audioInfoRegex.Matches(manifestData); 
    List<long> videoBitrates = new List<long>(); 
    List<long> audioBitrates = new List<long>(); 

    foreach (Match match in videoMatches) 
    { 
     long bitrate; 

     if (long.TryParse(match.Groups["bitrate"] 
           .Value, 
          out bitrate)) 
     { 
      videoBitrates.Add(bitrate); 
     } 
    } 

    foreach (Match match in audioMatches) 
    { 
     long bitrate; 

     if (long.TryParse(match.Groups["bitrate"] 
           .Value, 
          out bitrate)) 
     { 
      audioBitrates.Add(bitrate); 
     } 
    } 

    if (videoBitrates.Any() && audioBitrates.Any()) 
    { 
     IEnumerable<long> availableBitrate = videoBitrates.Where(b => b >= Settings.VideoQuality.ToBitRate()); 
     long videoBitrateSelected = availableBitrate.Any() ? availableBitrate.First() : videoBitrates.Max(); 
     long totalAudioBitrate = audioBitrates.Sum(); 

     return videoBitrateSelected + totalAudioBitrate; 
    } 

    return 0; 
} 
関連する問題