예제 #1
0
        public void DidCompleteForMediaSelection(NSUrlSession session, AVAggregateAssetDownloadTask aggregateAssetDownloadTask, AVMediaSelection mediaSelection)
        {
            /*
             * This delegate callback provides an AVMediaSelection object which is now fully available for
             * offline use. You can perform any additional processing with the object here.
             */

            Asset asset = null;

            activeDownloadsMap.TryGetValue(aggregateAssetDownloadTask, out asset);

            if (asset == null || Asset.Keys.Name != asset.Stream.Name)
            {
                return;
            }

            aggregateAssetDownloadTask.TaskDescription = asset.Stream.Name;
            aggregateAssetDownloadTask.Resume();

            var userInfo = new Dictionary <string, string>();

            userInfo[Asset.Keys.DownloadState] = new NSString(Asset.Keys.DownloadState.ToString());
            userInfo[Asset.Keys.DownloadSelectionDisplayName] = new NSString(GetDisplayNamesForSelectedMediaOptions(mediaSelection));

            var userInfoDictionary = NSDictionary.FromObjectsAndKeys(userInfo.Values.ToArray(), userInfo.Keys.ToArray());

            NSNotificationCenter.DefaultCenter.PostNotificationName(AssetPersistenceManager.AssetDownloadStateChanged, null, userInfoDictionary);
        }
예제 #2
0
        public void DidLoadTimeRange(NSUrlSession session, AVAggregateAssetDownloadTask aggregateAssetDownloadTask, CoreMedia.CMTimeRange timeRange, NSValue[] loadedTimeRanges, CoreMedia.CMTimeRange timeRangeExpectedToLoad, AVMediaSelection mediaSelection)
        {
            // This delegate callback should be used to provide download progress for your AVAssetDownloadTask.
            if (!activeDownloadsMap.ContainsKey(aggregateAssetDownloadTask))
            {
                return;
            }

            var asset = activeDownloadsMap[aggregateAssetDownloadTask];

            var percentComplete = 0.0;

            foreach (var value in loadedTimeRanges)
            {
                var loadedTimeRange = value.CMTimeRangeValue;
                percentComplete += loadedTimeRange.Duration.Seconds / timeRangeExpectedToLoad.Duration.Seconds;
            }

            var userInfo = new Dictionary <string, object>();

            userInfo[Asset.Keys.Name] = new NSString(asset.Stream.Name);
            userInfo[Asset.Keys.PercentDownloaded] = new NSNumber(percentComplete);

            var userInfoDictionary = NSDictionary.FromObjectsAndKeys(userInfo.Values.ToArray(), userInfo.Keys.ToArray());

            NSNotificationCenter.DefaultCenter.PostNotificationName(AssetPersistenceManager.AssetDownloadProgress, null, userInfoDictionary);
        }
예제 #3
0
        public void WillDownloadToUrl(NSUrlSession session, AVAggregateAssetDownloadTask aggregateAssetDownloadTask, NSUrl location)
        {
            /*
             * This delegate callback should only be used to save the location URL
             * somewhere in your application. Any additional work should be done in
             * `URLSessionTaskDelegate.urlSession(_:task:didCompleteWithError:)`.
             */

            willDownloadToUrlMap[aggregateAssetDownloadTask] = location;
        }
예제 #4
0
        internal void DownloadAssetStream(Asset asset)
        {
            // Get the default media selections for the asset's media selection groups.
            var preferredMediaSelection = asset.UrlAsset.PreferredMediaSelection;

            ///*
            // Creates and initializes an AVAggregateAssetDownloadTask to download multiple AVMediaSelections
            // on an AVURLAsset.

            // For the initial download, we ask the URLSession for an AVAssetDownloadTask with a minimum bitrate
            // corresponding with one of the lower bitrate variants in the asset.
            // */

            AVAggregateAssetDownloadTask task = null;

            try
            {
                var dictionary = new NSDictionary <NSString, NSObject>(new NSString("AVAssetDownloadTaskMinimumRequiredMediaBitrateKey"), (NSObject)(new NSNumber(265_000)));

                task = assetDownloadUrlSession.GetAssetDownloadTask(asset.UrlAsset,
                                                                    new AVMediaSelection[] { preferredMediaSelection },
                                                                    asset.Stream.Name,
                                                                    null,
                                                                    dictionary);
                task.TaskDescription = asset.Stream.Name;

                activeDownloadsMap.Add(task, asset);
                task.Resume();

                var userInfo = new Dictionary <string, object>();
                userInfo[Asset.Keys.Name]          = asset.Stream.Name;
                userInfo[Asset.Keys.DownloadState] = AssetDownloadState.Downloading.ToString();
                userInfo[Asset.Keys.DownloadSelectionDisplayName] = GetDisplayNamesForSelectedMediaOptions(preferredMediaSelection);

                var userInfoDictionary = NSDictionary.FromObjectsAndKeys(userInfo.Values.ToArray(), userInfo.Keys.ToArray());

                NSNotificationCenter.DefaultCenter.PostNotificationName(AssetPersistenceManager.AssetDownloadStateChanged, null, userInfoDictionary);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }
예제 #5
0
        public async Task RestorePersistenceManager()
        {
            if (didRestorePersistenceManager)
            {
                return;
            }

            didRestorePersistenceManager = true;

            // Grab all the tasks associated with the assetDownloadURLSession
            TaskCompletionSource <NSUrlSessionTask[]> tcs = new TaskCompletionSource <NSUrlSessionTask[]>();

            assetDownloadUrlSession.GetAllTasks((tasks) => tcs.TrySetResult(tasks));

            await tcs.Task;

            if (!tcs.Task.IsCompleted)
            {
                throw new Exception("Error restoring persistence manager state", tcs.Task?.Exception);
            }

            foreach (var task in tcs.Task?.Result)
            {
                if (!(task is AVAggregateAssetDownloadTask))
                {
                    break;
                }

                AVAggregateAssetDownloadTask assetDownloadTask = task as AVAggregateAssetDownloadTask;
                var assetName = assetDownloadTask.TaskDescription;
                var urlAsset  = assetDownloadTask.UrlAsset;
                var stream    = StreamListManager.Current.Streams.FirstOrDefault(i => i.Name == assetName);
                var asset     = new Asset(stream, urlAsset);

                activeDownloadsMap[assetDownloadTask] = asset;
            }

            NSNotificationCenter.DefaultCenter.PostNotificationName(AssetPersistenceManager.AssetPersistenceManagerDidRestoreState, null);
        }
예제 #6
0
        public void DidCompleteWithError(NSUrlSession session, NSUrlSessionTask task, NSError error)
        {
            var userDefaults = NSUserDefaults.StandardUserDefaults;

            Asset asset       = null;
            NSUrl downloadURL = null;
            AVAggregateAssetDownloadTask avTask = task as AVAggregateAssetDownloadTask;

            if (avTask == null ||
                !activeDownloadsMap.TryGetValue(avTask, out asset) ||
                !willDownloadToUrlMap.TryGetValue(avTask, out downloadURL))
            {
                return;
            }

            var userInfo = new Dictionary <string, string>();

            userInfo[Asset.Keys.Name] = new NSString(asset.Stream.Name);

            if (error != null)
            {
                switch (error.Code)
                {
                case (int)NSUrlError.Cancelled:

                    /*
                     * This task was canceled, you should perform cleanup using the
                     * URL saved from AVAssetDownloadDelegate.urlSession(_:assetDownloadTask:didFinishDownloadingTo:).
                     */
                    var localFileLocation = LocalAssetForStream(asset.Stream.Name)?.UrlAsset.Url;

                    if (localFileLocation == null)
                    {
                        return;
                    }

                    try
                    {
                        NSError err = null;
                        NSFileManager.DefaultManager.Remove(localFileLocation, out err);
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine($"An error occured trying to delete the contents on disk for {asset.Stream.Name}: {ex.Message}");
                    }

                    userInfo[Asset.Keys.DownloadState] = new NSString(AssetDownloadState.NotDownloaded.ToString());

                    break;

                case (int)NSUrlError.Unknown:
                    throw new Exception("Downloading HLS streams is not supported in the simulator.");

                default:
                    throw new Exception($"An unexpected error occured {error.Domain}");
                }
            }
            else
            {
                try
                {
                    NSError err;

                    var bookmark = downloadURL.CreateBookmarkData(default(NSUrlBookmarkCreationOptions), new string[] { asset.Stream.Name }, downloadURL.AbsoluteUrl, out err);
                    userDefaults.SetValueForKey(bookmark, new NSString(asset.Stream.Name));
                }
                catch (Exception ex)
                {
                    Debug.WriteLine($"Failed to create bookmarkData for download URL: {ex.Message}");
                }

                userInfo[Asset.Keys.DownloadState] = AssetDownloadState.Downloaded.ToString();
                userInfo[Asset.Keys.DownloadSelectionDisplayName] = string.Empty;
            }

            var userInfoDictionary = NSDictionary.FromObjectsAndKeys(userInfo.Values.ToArray(), userInfo.Keys.ToArray());

            NSNotificationCenter.DefaultCenter.PostNotificationName(AssetPersistenceManager.AssetDownloadStateChanged, null, userInfoDictionary);
        }
예제 #7
0
        internal void CancelAssetDownload(Asset asset)
        {
            AVAggregateAssetDownloadTask task = activeDownloadsMap.Where(i => i.Value == asset).Select(i => i.Key).FirstOrDefault();

            task?.Cancel();
        }