UIKitCatalog/VideoPlayerViewController.swift
/* |
Copyright (C) 2017 Apple Inc. All Rights Reserved. |
See LICENSE.txt for this sample’s licensing information |
Abstract: |
A view controller that demonstrates how to present an `AVPlayerViewController` for an `AVPlayerItem` with metadata and timings. |
*/ |
import UIKit |
import AVKit |
class VideoPlayerViewController: UIViewController, AVPlayerViewControllerDelegate { |
// MARK: IB Actions |
@IBAction func playVideo(_ sender: AnyObject) { |
// Create an AVAsset with for the media's URL. |
let mediaURL = URL(string: "http://p.events-delivery.apple.com.edgesuite.net/1509pijnedfvopihbefvpijlkjb/m3u8/hls_vod_mvp.m3u8")! |
let asset = AVAsset(url: mediaURL) |
/* |
Create an `AVPlayerItem` for the `AVAsset` and populate it with information |
about the video. |
*/ |
let playerItem = AVPlayerItem(asset: asset) |
playerItem.externalMetadata = sampleExternalMetaData() |
playerItem.navigationMarkerGroups = [sampleNavigationMarkerGroup()] |
playerItem.interstitialTimeRanges = sampleInterstitialTimeRanges() |
// Create and present an `AVPlayerViewController`. |
let playerViewController = AVPlayerViewController() |
playerViewController.delegate = self |
let player = AVPlayer(playerItem: playerItem) |
playerViewController.player = player |
self.present(playerViewController, animated: true) { |
/* |
Begin playing the media as soon as the controller has |
been presented. |
*/ |
player.play() |
} |
} |
// MARK: AVPlayerViewControllerDelegate |
func playerViewController(_ playerViewController: AVPlayerViewController, willPresent interstitial: AVInterstitialTimeRange) { |
// Prevent the user from skipping intersitials. |
playerViewController.requiresLinearPlayback = true |
} |
func playerViewController(_ playerViewController: AVPlayerViewController, didPresent interstitial: AVInterstitialTimeRange) { |
/* |
Allow the user to navigate anywhere in the video once an interstitial |
has been played. |
*/ |
playerViewController.requiresLinearPlayback = false |
} |
// MARK: Meta data |
func sampleExternalMetaData() -> [AVMetadataItem] { |
let titleItem = AVMutableMetadataItem() |
titleItem.identifier = AVMetadataCommonIdentifierTitle |
titleItem.value = "Apple Special Event, September 2015" as NSString |
titleItem.extendedLanguageTag = "und" |
let descriptionItem = AVMutableMetadataItem() |
descriptionItem.identifier = AVMetadataCommonIdentifierDescription |
descriptionItem.value = "Check out iPhone 6s and iPhone 6s Plus, learn about the powerful iPad Pro, take a look at the new features and bands for Apple Watch, and see the premiere of the all-new Apple TV." as NSString |
descriptionItem.extendedLanguageTag = "und" |
return [titleItem, descriptionItem] |
} |
func sampleNavigationMarkerGroup() -> AVNavigationMarkersGroup { |
let group = AVNavigationMarkersGroup(title: "Announcements", timedNavigationMarkers: [ |
timedMetaDataGroupWithTitle("Apple Watch", startTime: 90, endTime: 917), |
timedMetaDataGroupWithTitle("iPad Pro", startTime: 917, endTime: 1691), |
timedMetaDataGroupWithTitle("Apple Pencil", startTime: 1691, endTime: 3105), |
timedMetaDataGroupWithTitle("Apple TV", startTime: 3105, endTime: 4968), |
timedMetaDataGroupWithTitle("iPhone", startTime: 4968, endTime: 7328) |
]) |
return group |
} |
func sampleInterstitialTimeRanges() -> [AVInterstitialTimeRange] { |
let ranges = [ |
AVInterstitialTimeRange(timeRange: timeRange(withStartTime: 728, duration: 53)), |
AVInterstitialTimeRange(timeRange: timeRange(withStartTime: 1015, duration: 55)), |
AVInterstitialTimeRange(timeRange: timeRange(withStartTime: 3305, duration: 759)), |
AVInterstitialTimeRange(timeRange: timeRange(withStartTime: 7261, duration: 61)) |
] |
return ranges |
} |
// MARK: Convenience |
func timedMetaDataGroupWithTitle(_ title: String, startTime: TimeInterval, endTime: TimeInterval) -> AVTimedMetadataGroup { |
// Create an `AVMetadataItem` for the title. |
let titleItem = AVMutableMetadataItem() |
titleItem.identifier = AVMetadataCommonIdentifierTitle |
titleItem.value = title as NSString |
titleItem.extendedLanguageTag = "und" |
// Create a `CMTimeRange` from the supplied information. |
let range = timeRange(from: startTime, to: endTime) |
return AVTimedMetadataGroup(items: [titleItem], timeRange: range) |
} |
func timeRange(from startTime: TimeInterval, to endTime: TimeInterval) -> CMTimeRange { |
let cmStartTime = CMTimeMakeWithSeconds(Float64(startTime), 100) |
let cmEndTime = CMTimeMakeWithSeconds(Float64(endTime), 100) |
let timeRange = CMTimeRangeFromTimeToTime(cmStartTime, cmEndTime) |
return timeRange |
} |
func timeRange(withStartTime startTime: TimeInterval, duration: TimeInterval) -> CMTimeRange { |
let cmStartTime = CMTimeMakeWithSeconds(Float64(startTime), 100) |
let cmDuration = CMTimeMakeWithSeconds(Float64(duration), 100) |
let timeRange = CMTimeRange(start: cmStartTime, duration: cmDuration) |
return timeRange |
} |
} |
Copyright © 2017 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2017-02-02