diff --git a/Pod/Classes/internal/WistiaPlayer_internal.swift b/Pod/Classes/internal/WistiaPlayer_internal.swift index 32ce650..eca2707 100644 --- a/Pod/Classes/internal/WistiaPlayer_internal.swift +++ b/Pod/Classes/internal/WistiaPlayer_internal.swift @@ -75,28 +75,32 @@ internal extension WistiaPlayer { if let slug = assetSlug { if let assetMatchingSlug = (media.assets.filter { $0.slug == slug }).first { guard assetMatchingSlug.status == .Ready else { throw URLDeterminationError.AssetNotReady(asset: assetMatchingSlug) } - delegate?.wistiaPlayer(self, willLoadVideoForAsset: assetMatchingSlug, fromMedia: media) + delegate?.wistiaPlayer(self, willLoadVideoForMedia: media, usingAsset: assetMatchingSlug, usingHLSMasterIndexManifest: false) return assetMatchingSlug.url } else { throw URLDeterminationError.NoAsset } } - //Preffered playback of HLS assets, which come in m3u8 containers + // If HLS is required we use the "manifest of manifests" that includes all of the alternate streams + if requireHLS { + delegate?.wistiaPlayer(self, willLoadVideoForMedia: media, usingAsset: nil, usingHLSMasterIndexManifest: true) + return media.hlsMasterIndexManifestURL + } + + //If HLS isn't required, still prefer playback of HLS assets, which come in m3u8 containers let preferredAssets = media.assets.filter { $0.container == "m3u8" } if let asset = largestAssetIn(preferredAssets, withoutGoingUnder: targetWidth) { guard asset.status == .Ready else { throw URLDeterminationError.AssetNotReady(asset: asset) } - delegate?.wistiaPlayer(self, willLoadVideoForAsset: asset, fromMedia: media) + delegate?.wistiaPlayer(self, willLoadVideoForMedia: media, usingAsset: asset, usingHLSMasterIndexManifest: false) return asset.url - } else if requireHLS { - throw URLDeterminationError.NoHLSAsset } // We can also playback assets in the mp4 container. let playableAssets = media.assets.filter { $0.container == "mp4" } if let asset = largestAssetIn(playableAssets, withoutGoingUnder: targetWidth) { guard asset.status == .Ready else { throw URLDeterminationError.AssetNotReady(asset: asset) } - delegate?.wistiaPlayer(self, willLoadVideoForAsset: asset, fromMedia: media) + delegate?.wistiaPlayer(self, willLoadVideoForMedia: media, usingAsset: asset, usingHLSMasterIndexManifest: false) return asset.url } else { throw URLDeterminationError.NoAsset diff --git a/Pod/Classes/internal/view controller/WistiaPlayerViewController_internal.swift b/Pod/Classes/internal/view controller/WistiaPlayerViewController_internal.swift index d9a2ece..a1f9241 100644 --- a/Pod/Classes/internal/view controller/WistiaPlayerViewController_internal.swift +++ b/Pod/Classes/internal/view controller/WistiaPlayerViewController_internal.swift @@ -206,7 +206,7 @@ extension WistiaPlayerViewController: WistiaPlayerDelegate { self.pause() } - public func wistiaPlayer(player: WistiaPlayer, willLoadVideoForAsset asset: WistiaAsset, fromMedia media:WistiaMedia) { + public func wistiaPlayer(player: WistiaPlayer, willLoadVideoForMedia media: WistiaMedia, usingAsset asset: WistiaAsset?, usingHLSMasterIndexManifest: Bool) { if media.spherical { playing360 = true player360View.hidden = false diff --git a/Pod/Classes/public/WistiaPlayer.swift b/Pod/Classes/public/WistiaPlayer.swift index ef5ab75..6b4eeb8 100644 --- a/Pod/Classes/public/WistiaPlayer.swift +++ b/Pod/Classes/public/WistiaPlayer.swift @@ -80,10 +80,13 @@ public protocol WistiaPlayerDelegate : class { that will always be the one used. Otherwise, heuristics will use the current value of `requireHLS` and device characteristics to select the best asset. - - Parameter asset: The `WistiaAsset` that will be loaded for playback. - Parameter media: The `WistiaMedia` from which this asset was chosen. + - Parameter asset: The `WistiaAsset` that will be loaded for playback, if the HLS master index manifest was not used. + - Parameter usingHLSMasterIndexManifest: `True` iff playback is using the HLS master index manifest + (aka Manifest of Manifests). `asset` will be `nil`. + */ - func wistiaPlayer(player:WistiaPlayer, willLoadVideoForAsset asset:WistiaAsset, fromMedia media:WistiaMedia) + func wistiaPlayer(player:WistiaPlayer, willLoadVideoForMedia media:WistiaMedia, usingAsset asset:WistiaAsset?, usingHLSMasterIndexManifest: Bool) } @@ -120,21 +123,23 @@ public final class WistiaPlayer: NSObject { `WistiaPlayer` has been initialized for playback - Parameter referrer: The referrer shown when viewing your video statstics on Wistia. - + \ We recommend using a universal link to the video. This will allow you to click that link from the Wistia stats page while still recording the in-app playback location. - + \ In the case it can't be a universal link, it should be a descriptive string identifying the location (and possibly state) of your app where this video isbeing played back eg. _ProductTourViewController_ or _SplashViewController.page1(uncoverted_email)_ - - Parameter requireHLS: Should this player choose only HLS assets for playback (failing if there is not one available - for any given `WistiaMedia` or `hashedID`)? - + - Parameter requireHLS: Should this player use only the HLS master index manifest for playback (failing if there + is not one available for any given `WistiaMedia` or `hashedID`)? + \ Apple requires HLS for video over 10m in length played over cellular connections. - + \ Default, which we recommend, is `true`. + \ + **NOTE:** You must have HLS enabled for your Wistia account. Contact support@wistia.com if you're not sure. - Returns: An idle `WistiaPlayer` not yet displayed. */ @@ -156,21 +161,23 @@ public final class WistiaPlayer: NSObject { - Parameter hashedID: The ID of the media you wish to load asynchronously. - Parameter referrer: The referrer shown when viewing your video statstics on Wistia. - + \ We recommend using a universal link to the video. This will allow you to click that link from the Wistia stats page while still recording the in-app playback location. - + \ In the case it can't be a universal link, it should be a descriptive string identifying the location (and possibly state) of your app where this video isbeing played back eg. _ProductTourViewController_ or _SplashViewController.page1(uncoverted_email)_ - - Parameter requireHLS: Should this player choose only HLS assets for playback (failing if there is not one available - for any given `WistiaMedia` or `hashedID`)? - + - Parameter requireHLS: Should this player use only the HLS master index manifest for playback (failing if there + is not one available for any given `WistiaMedia` or `hashedID`)? + \ Apple requires HLS for video over 10m in length played over cellular connections. - + \ Default, which we recommend, is `true`. + \ + **NOTE:** You must have HLS enabled for your Wistia account. Contact support@wistia.com if you're not sure. - Returns: A `WistiaPlayer` that is initialized and asynchronously loading the media for playback. */ diff --git a/Pod/Classes/public/WistiaPlayerViewController.swift b/Pod/Classes/public/WistiaPlayerViewController.swift index 2f903a8..e0aa081 100644 --- a/Pod/Classes/public/WistiaPlayerViewController.swift +++ b/Pod/Classes/public/WistiaPlayerViewController.swift @@ -90,21 +90,23 @@ Initialize a new `WistiaPlayerViewController` without an initial video for playback. - Parameter referrer: The referrer shown when viewing your video statstics on Wistia. - - We recommend using a universal link to the video. - This will allow you to click that link from the Wistia stats page - while still recording the in-app playback location. - - In the case it can't be a universal link, it should be a descriptive string identifying the location - (and possibly state) of your app where this video isbeing played back - eg. _ProductTourViewController_ or _SplashViewController.page1(uncoverted_email)_ - - - Parameter requireHLS: Should this player choose only HLS assets for playback (failing if there is not one available - for any given `WistiaMedia` or `hashedID`)? - - Apple requires HLS for video over 10m in length played over cellular connections. - - Default, which we recommend, is `true`. + \ + We recommend using a universal link to the video. + This will allow you to click that link from the Wistia stats page + while still recording the in-app playback location. + \ + In the case it can't be a universal link, it should be a descriptive string identifying the location + (and possibly state) of your app where this video isbeing played back + eg. _ProductTourViewController_ or _SplashViewController.page1(uncoverted_email)_ + + - Parameter requireHLS: Should this player use only the HLS master index manifest for playback (failing if there + is not one available for any given `WistiaMedia` or `hashedID`)? + \ + Apple requires HLS for video over 10m in length played over cellular connections. + \ + Default, which we recommend, is `true`. + \ + **NOTE:** You must have HLS enabled for your Wistia account. Contact support@wistia.com if you're not sure. - Returns: An idle `WistiaPlayerViewController` not yet displayed. */ diff --git a/Pod/Classes/public/model/WistiaMedia.swift b/Pod/Classes/public/model/WistiaMedia.swift index be2eec5..37a46a5 100644 --- a/Pod/Classes/public/model/WistiaMedia.swift +++ b/Pod/Classes/public/model/WistiaMedia.swift @@ -46,6 +46,23 @@ public struct WistiaMedia { /// The visual and behavioral customizations to apply to this media public var embedOptions: WistiaMediaEmbedOptions? + /** + The URL serving the master index manifest for HLS streams. This manifest includes references to all of the + alternate HLS streams and is used by AVKit to dynamically choose the best stream for current conditions. + + The Wistia HLS alternate streams and master index manifest are engineered specificaly to satisfy Apple's + HLS requirements for the App Store. + + - Note: The Master index manifest may also be called the "manifest of manifests" in some places. + + - Note: Not all `WistiaMedia` has HLS derivatives available yet. + */ + public var hlsMasterIndexManifestURL: NSURL { + get { + return NSURL(string: "https://fast.wistia.net/embed/medias/\(self.hashedID).m3u8")! + } + } + // MARK: - ------------Internal------------ var distilleryURLString: String? var accountKey: String?