SlideShare ist ein Scribd-Unternehmen logo
1 von 62
Downloaden Sie, um offline zu lesen
Video Killed The Rolex
Star
Chris Adamson • @invalidname
CocoaConf San Jose • November, 2015
Media Support in
watchOS 2.0
watchOS 2.0
• App Extension runs on watch, not on iPhone
• New watchOS APIs for media playback and
recording
• Prepare yourself, they’re limited!
From watchOS 2.0 Transition Guide
You must implement your extension using
the frameworks in the watchOS SDK instead
of the iOS SDK. For any features not
available in the provided frameworks, you
must rely on your iPhone app to perform the
corresponding task.
From watchOS 2.0 Transition Guide
Your extension now stores files and data on
Apple Watch. Any data that is not part of your
Watch app or WatchKit extension bundle must
be fetched the network or from the companion
iOS app running on the user’s iPhone. You
cannot rely on a shared group container to
exchange files with your iOS app. Fetching files
involves transferring them wirelessly to Apple
Watch.
Media files. The Watch app handles audio
and video playback in your app. If your
WatchKit extension downloads media files
from the network or the companion iOS app,
you must place those files in a shared group
container that is accessible to both your Watch
app and WatchKit extension. For more
information about managing media-related
files, see Managing Your Media
From watchOS 2.0 Transition Guide
Media functionality
• Video playback
• Audio playback
• Audio recording
Video Playback
• WKInterfaceMovie — Canned UI component for
movie playback
• WKInterfaceController — A/V features provided
by primary UI controller class
WKInterfaceMovie
A WKInterfaceMovie object lets you play
back video and audio content directly from
your interface. A movie object displays a
poster image with a play button on top of it.
When the user taps the play button, WatchKit
plays the movie in a modal interface.
// WKInterfaceMovie.h
// WatchKit
WK_AVAILABLE_WATCHOS_ONLY(2.0)
@interface WKInterfaceMovie : WKInterfaceObject
- (void)setMovieURL:(NSURL *)URL;
- (void)setVideoGravity:(WKVideoGravity)videoGravity; // default is
WKVideoGravityResizeAspect
- (void)setLoops:(BOOL)loops;
- (void)setPosterImage:(nullable WKImage *)posterImage;
@end
Video Gravity
• Conceptually identical to video gravity constants in AV
Foundation
• Resize — stretch pixels to fill container
• Aspect (Fit) — honoring aspect ratio, scale to reach
one set of bounds (top/bottom or right/left), then
letter-/pillar-box
• Aspect Fill — honoring aspect ratio, scale to reach
both sets of bounds, allowing contents to be
clipped if needed
Original 16:9 Frame
WKVideoGravity.

ResizeAspect
This is the default for WKInterfaceMovie.videoGravity
WKVideoGravity.

ResizeAspectFill
WKVideoGravity.Resize
Please never do this
WKInterfaceController
• Media playback and recording methods
provided by the base controller class
• Can use these to play video whenever the app
decides it’s time to do so
- (void)presentMediaPlayerControllerWithURL:(NSURL *)URL

options:(nullable NSDictionary *)options

completion:(void(^)(BOOL didPlayToEnd,

NSTimeInterval endTime,

NSError * __nullable error))completion

WK_AVAILABLE_WATCHOS_ONLY(2.0);
- (void)dismissMediaPlayerController WK_AVAILABLE_WATCHOS_ONLY(2.0);
options dictionary of presentMediaPlayerController takes
WKVideoGravity key, uses the WKVideoGravity constants
Video Considerations
1280x720 320x180
921,600 pixels 57,600 pixels
1/16 the size!
Encoding Guidelines
• Video Codec: H.264 High profile
• Bitrate: 160 kbps, 30 frames/sec
• Size: 320x180 (landscape), 208x260 (portrait)
• Audio: 32 kbps
160 kbps video
93% smaller file size!
WKInterfaceController Audio
• Playback works just like video
• Same recommendation for audio bitrate: 32
kbps
• Audio playback always uses Bluetooth
headphones/speakers if paired, otherwise
internal speaker
Audio Recording
-(void)presentAudioRecordingControllerWithOutputURL:(NSURL *)URL

preset:(WKAudioRecordingPreset)preset

maximumDuration:(NSTimeInterval)maximumDuration

actionTitle:(nullable NSString *)actionTitle

completion:(void (^)(BOOL didSave,

NSError * __nullable error))completion

WK_AVAILABLE_WATCHOS_ONLY(2.0);
- (void)dismissAudioRecordingController
WK_AVAILABLE_WATCHOS_ONLY(2.0);
presentAudioRecording

ControllerWithOutputURL:
• actionTitle — A string to use in an “end recording”
button once audio capture is underway
• preset — WKAudioRecording quality preset
• NarrowBandSpeech (8 kHz sampling, 24 kbps
AAC)
• WideBandSpeech (16 kHz sampling, 32 kbps AAC)
• HighQualityAudio (44.1 kHz sampling, 96 kbps
AAC)
Audio Player
• “Headless” API for playing audio
programmatically
• Assumes app provides own UI, or doesn’t
have one
WKAudioFileAsset
+ (instancetype)assetWithURL:(NSURL *)URL;
+ (instancetype)assetWithURL:(NSURL *)URL

title:(nullable NSString *)title

albumTitle:(nullable NSString *)albumTitle

artist:(nullable NSString *)artist;
WKAudioFilePlayerItem
• status — .Unknown, .ReadyToPlay, .Failed
• Notifications — Time jumped, Played to End,
Failed to Play to End
+ (WKAudioFilePlayerItem *)playerItemWithAsset:(WKAudioFileAsset
*)asset;
@property (nonatomic, readonly) WKAudioFileAsset *asset;
@property (nonatomic, readonly) WKAudioFilePlayerItemStatus status;
@property (nonatomic, readonly, nullable) NSError *error;
@property (nonatomic, readonly) NSTimeInterval currentTime;
WKAudioFilePlayer
+ (instancetype)playerWithPlayerItem:

(WKAudioFilePlayerItem *)item;
- (void)play;
- (void)pause;
- (void)replaceCurrentItemWithPlayerItem:

(nullable WKAudioFilePlayerItem *)item;
@property(nonatomic, readonly, nullable) WKAudioFilePlayerItem
*currentItem;
@property (nonatomic, readonly) WKAudioFilePlayerStatus
status;
@property (nonatomic, readonly, nullable) NSError *error;
@property (nonatomic) float rate;
@property (nonatomic, readonly) NSTimeInterval currentTime;
WKAudioFileQueuePlayer
@interface WKAudioFileQueuePlayer : WKAudioFilePlayer
+ (instancetype)queuePlayerWithItems:

(NSArray<WKAudioFilePlayerItem *> *)items;
- (void)advanceToNextItem;
- (void)appendItem:(WKAudioFilePlayerItem *)item;
- (void)removeItem:(WKAudioFilePlayerItem *)item;
- (void)removeAllItems;
@property(nonatomic, readonly) NSArray<WKAudioFilePlayerItem
*> *items;
@end
And that’s it!
Video Killed The Rolex
Star
Chris Adamson • @invalidname
CocoaConf San Jose • November, 2015
Slides available at slideshare.net/invalidname
Code (eventually) at github.com/invalidname
Now wait a darn
minute!
AVFoundation, Core Image, and Core Audio are
huge and complex, but required for lots of app
types. Will any audio, video, or image APIs be
available? Will they only be possible through
limited, high-level interfaces?
http://www.marco.org/2015/05/28/watch-sdk-questions
Available System Technologies
Extensions built specifically for watchOS 2 have access to the
following system frameworks:
ClockKit
Contacts
Core Data
Core Foundation
Core Graphics
Core Location
Core Motion
EventKit
Foundation
HealthKit
HomeKit
ImageIO
MapKit
Mobile Core Services
PassKit
Security
Watch Connectivity
WatchKit
Notice the absence of AV Foundation, Core Audio, Core
Media, and Core Video
From watchOS 2.0 Transition Guide
You must implement your extension using
the frameworks in the watchOS SDK instead
of the iOS SDK. For any features not
available in the provided frameworks, you
must rely on your iPhone app to perform the
corresponding task.
overcast.fm
AUGraph
AUFilePlayer AURemoteIO
AVAudioEngine is conceptually similar, but can’t do a
step we need later, so this is the Core Audio approach
AUGraph
AUFilePlayer AURemoteIO
AUNew
TimePitch
Offline AUGraphs
AUFilePlayer
AUGeneric
Output
AUNew
TimePitch
AudioUnit
Render()
+
ExtAudioFile
Write()
OSStatus timeShift(NSURL *inSourceURL, NSURL *inDestinationURL, float inSpeed) {
OSStatus err = noErr;
// crate graph
AUGraph auGraph;
err = NewAUGraph(&auGraph);
if (err != noErr) {goto fail;} // goto fail, go directly to fail...
AudioComponentDescription compDesc = {0};
// file player
NSLog (@"Making AUFilePlayer");
AUNode filePlayerNode;
AudioUnit filePlayerUnit;
compDesc.componentType = kAudioUnitType_Generator;
compDesc.componentSubType = kAudioUnitSubType_AudioFilePlayer;
compDesc.componentManufacturer = kAudioUnitManufacturer_Apple;
err = AUGraphAddNode(auGraph, &compDesc, &filePlayerNode);
if (err != noErr) {goto fail;} // goto fail, go directly to fail...
err = AUGraphNodeInfo(auGraph, filePlayerNode, NULL, &filePlayerUnit);
if (err != noErr) {goto fail;} // goto fail, go directly to fail...
// AUNewTimePitch
NSLog (@"Making AUNewTimePitch");
AUNode timePitchNode;
AudioUnit timePitchUnit;
memset(&compDesc, 0, sizeof(compDesc));
compDesc.componentType = kAudioUnitType_FormatConverter;
compDesc.componentSubType = kAudioUnitSubType_NewTimePitch;
compDesc.componentManufacturer = kAudioUnitManufacturer_Apple;
// and another 100 lines or so of this!
?
Watch Connectivity
The Watch Connectivity framework
(WatchConnectivity.framework)
provides a two-way communications conduit
between an iOS app and a WatchKit
extension on a paired Apple Watch. Apps
use this framework to pass files and data
back and forth. Most transfers happen in the
background when the receiving app is
inactive. When the app wakes up, it is
notified of any data that arrived while it was
inactive. Live communication is also possible
when both apps are active.
Demo (beginning)
Phone: Activate WCSession
if WCSession.isSupported() {
WCSession.defaultSession().delegate = self
WCSession.defaultSession().activateSession()
NSLog ("iPhone WCSession ready")
}
Watch: Activate WCSession
if WCSession.isSupported() {
WCSession.defaultSession().delegate = self
WCSession.defaultSession().activateSession()
NSLog ("Watch WCSession ready")
}
Phone: transfer file
let transfer = WCSession.defaultSession().transferFile(url,
metadata: nil)
NSLog ("transferring: (transfer)")
//MARK: WatchConnectivity delegate
func session(session: WCSession,
didFinishFileTransfer fileTransfer: WCSessionFileTransfer,
error: NSError?) {
NSLog ("didFinishFileTransfer: (fileTransfer), error: (error)")
}
Watch: receive file
func session(session: WCSession, didReceiveFile file: WCSessionFile) {
NSLog ("didReceiveFile: (file)")
let docsURL = NSFileManager.defaultManager().URLsForDirectory(
NSSearchPathDirectory.DocumentDirectory,
inDomains: NSSearchPathDomainMask.UserDomainMask).first
let storageURL = docsURL?.URLByAppendingPathComponent(
file.fileURL.lastPathComponent!)
do {
try NSFileManager.defaultManager().copyItemAtURL(file.fileURL,
toURL: storageURL!)
pushControllerWithName("player", context: storageURL)
} catch let error as NSError {
NSLog ("copy error: (error)")
}
}
file: If you want to keep the file referenced by this parameter, you must move it synchronously to a new
location during your implementation of this method. If you do not move the file, the system deletes it after
this method returns.
Demo (continued!)
What about video?
AVAssetExportSession
AVAssetExportSession
Export Preset Names for Apple Devices
You use these export options to produce files that can be played on the specific
Apple devices.
Declaration
SWIFT
let AVAssetExportPresetAppleM4VCellular: String
let AVAssetExportPresetAppleM4ViPod: String
let AVAssetExportPresetAppleM4V480pSD: String
let AVAssetExportPresetAppleM4VAppleTV: String
let AVAssetExportPresetAppleM4VWiFi: String
let AVAssetExportPresetAppleM4V720pHD: String
let AVAssetExportPresetAppleM4V1080pHD: String
let AVAssetExportPresetAppleProRes422LPCM: String
AVAssetWriter
• Low-level access for writing media files
• Allows you to specify output size, encoding
settings, bitrate, etc.
• Requires you to write each CMSampleBuffer
individually
AVAssetWriterInput
SWIFT
let AVVideoCodecKey: String
let AVVideoCodecH264: String
let AVVideoCodecJPEG: String
let AVVideoCodecAppleProRes4444: String
let AVVideoCodecAppleProRes422: String
let AVVideoWidthKey: String
let AVVideoHeightKey: String
let AVVideoCompressionPropertiesKey: String
let AVVideoAverageBitRateKey: String
let AVVideoQualityKey: String
let AVVideoMaxKeyFrameIntervalKey: String
let AVVideoProfileLevelKey: String
let AVVideoProfileLevelH264Baseline30: String
let AVVideoProfileLevelH264Baseline31: String
let AVVideoProfileLevelH264Baseline41: String
let AVVideoProfileLevelH264Main30: String
let AVVideoProfileLevelH264Main31: String
let AVVideoProfileLevelH264Main32: String
let AVVideoProfileLevelH264Main41: String
let AVVideoProfileLevelH264High40: String
let AVVideoProfileLevelH264High41: String
let AVVideoPixelAspectRatioKey: String
let AVVideoPixelAspectRatioHorizontalSpacingKey:
String
let AVVideoPixelAspectRatioVerticalSpacingKey:
String
let AVVideoCleanApertureKey: String
let AVVideoCleanApertureWidthKey: String
let AVVideoCleanApertureHeightKey: String
let AVVideoCleanApertureHorizontalOffsetKey:
String
let AVVideoCleanApertureVerticalOffsetKey:
String
Video Settings
These constants define dictionary keys for configuring video
compression and compression settings for video assets.
- initWithMediaType:outputSettings:sourceFormatHint:
AVAssetReader
Output
AVAssetReader
Output
AVAssetWriter
Input
AVAssetWriter
Input
Audio path (output settings to change bitrate)
Video path (output settings to change size, encoding, bitrate)
Takeaways
• Basic support for file-based audio/video
playback and audio recording
• Playback files are either in your bundle or
downloaded by your iOS app + extension
• Any downloading or media processing needs to
be performed on your iPhone, then sent to watch
extension/app via Watch Connectivity
Video Killed The Rolex
Star
Chris Adamson • @invalidname
CocoaConf San Jose • November, 2015
Slides will be at slideshare.net/invalidname
Code (eventually, maybe) at github.com/invalidname

Weitere ähnliche Inhalte

Was ist angesagt?

Mastering Media with AV Foundation
Mastering Media with AV FoundationMastering Media with AV Foundation
Mastering Media with AV FoundationChris Adamson
 
Introduction to AV Foundation
Introduction to AV FoundationIntroduction to AV Foundation
Introduction to AV FoundationChris Adamson
 
Stupid Video Tricks (CocoaConf DC, March 2014)
Stupid Video Tricks (CocoaConf DC, March 2014)Stupid Video Tricks (CocoaConf DC, March 2014)
Stupid Video Tricks (CocoaConf DC, March 2014)Chris Adamson
 
Composing and Editing Media with AV Foundation
Composing and Editing Media with AV FoundationComposing and Editing Media with AV Foundation
Composing and Editing Media with AV FoundationBob McCune
 
Building Modern Audio Apps with AVAudioEngine
Building Modern Audio Apps with AVAudioEngineBuilding Modern Audio Apps with AVAudioEngine
Building Modern Audio Apps with AVAudioEngineBob McCune
 
Building A Streaming Apple TV App (CocoaConf DC, Sept 2016)
Building A Streaming Apple TV App (CocoaConf DC, Sept 2016)Building A Streaming Apple TV App (CocoaConf DC, Sept 2016)
Building A Streaming Apple TV App (CocoaConf DC, Sept 2016)Chris Adamson
 
Master Video with AV Foundation
Master Video with AV FoundationMaster Video with AV Foundation
Master Video with AV FoundationBob McCune
 
AVFoundation @ TACOW 2013 05 14
AVFoundation @ TACOW 2013 05 14AVFoundation @ TACOW 2013 05 14
AVFoundation @ TACOW 2013 05 14Ryder Mackay
 
Managing Eclipse Preferences for Teams (EclipseCon 2011)
Managing Eclipse Preferences for Teams (EclipseCon 2011)Managing Eclipse Preferences for Teams (EclipseCon 2011)
Managing Eclipse Preferences for Teams (EclipseCon 2011)Netcetera
 
Core audio
Core audioCore audio
Core audioscussen
 
#startathon2.0 - Spark Core
#startathon2.0 - Spark Core#startathon2.0 - Spark Core
#startathon2.0 - Spark Coresl2square
 
Game programming with Groovy
Game programming with GroovyGame programming with Groovy
Game programming with GroovyJames Williams
 
aptly: Debian repository management tool
aptly: Debian repository management toolaptly: Debian repository management tool
aptly: Debian repository management toolAndrey Smirnov
 
Build HA Asterisk on Microsoft Azure using DRBD/Heartbeat
Build HA Asterisk on Microsoft Azure using DRBD/HeartbeatBuild HA Asterisk on Microsoft Azure using DRBD/Heartbeat
Build HA Asterisk on Microsoft Azure using DRBD/HeartbeatSanjay Willie
 
Plone in the Cloud - an on-demand CMS hosted on Amazon EC2
Plone in the Cloud - an on-demand CMS hosted on Amazon EC2Plone in the Cloud - an on-demand CMS hosted on Amazon EC2
Plone in the Cloud - an on-demand CMS hosted on Amazon EC2Jazkarta, Inc.
 
Introduction of openpear
Introduction of openpearIntroduction of openpear
Introduction of openpearSotaro Karasawa
 

Was ist angesagt? (20)

Mastering Media with AV Foundation
Mastering Media with AV FoundationMastering Media with AV Foundation
Mastering Media with AV Foundation
 
Introduction to AV Foundation
Introduction to AV FoundationIntroduction to AV Foundation
Introduction to AV Foundation
 
Stupid Video Tricks (CocoaConf DC, March 2014)
Stupid Video Tricks (CocoaConf DC, March 2014)Stupid Video Tricks (CocoaConf DC, March 2014)
Stupid Video Tricks (CocoaConf DC, March 2014)
 
Composing and Editing Media with AV Foundation
Composing and Editing Media with AV FoundationComposing and Editing Media with AV Foundation
Composing and Editing Media with AV Foundation
 
Building Modern Audio Apps with AVAudioEngine
Building Modern Audio Apps with AVAudioEngineBuilding Modern Audio Apps with AVAudioEngine
Building Modern Audio Apps with AVAudioEngine
 
Stupid Video Tricks
Stupid Video TricksStupid Video Tricks
Stupid Video Tricks
 
Building A Streaming Apple TV App (CocoaConf DC, Sept 2016)
Building A Streaming Apple TV App (CocoaConf DC, Sept 2016)Building A Streaming Apple TV App (CocoaConf DC, Sept 2016)
Building A Streaming Apple TV App (CocoaConf DC, Sept 2016)
 
Master Video with AV Foundation
Master Video with AV FoundationMaster Video with AV Foundation
Master Video with AV Foundation
 
AVFoundation @ TACOW 2013 05 14
AVFoundation @ TACOW 2013 05 14AVFoundation @ TACOW 2013 05 14
AVFoundation @ TACOW 2013 05 14
 
Managing Eclipse Preferences for Teams (EclipseCon 2011)
Managing Eclipse Preferences for Teams (EclipseCon 2011)Managing Eclipse Preferences for Teams (EclipseCon 2011)
Managing Eclipse Preferences for Teams (EclipseCon 2011)
 
HTML5 Audio & Video
HTML5 Audio & VideoHTML5 Audio & Video
HTML5 Audio & Video
 
Core audio
Core audioCore audio
Core audio
 
#startathon2.0 - Spark Core
#startathon2.0 - Spark Core#startathon2.0 - Spark Core
#startathon2.0 - Spark Core
 
Game programming with Groovy
Game programming with GroovyGame programming with Groovy
Game programming with Groovy
 
Events+storm
Events+stormEvents+storm
Events+storm
 
Studio track1
Studio track1Studio track1
Studio track1
 
aptly: Debian repository management tool
aptly: Debian repository management toolaptly: Debian repository management tool
aptly: Debian repository management tool
 
Build HA Asterisk on Microsoft Azure using DRBD/Heartbeat
Build HA Asterisk on Microsoft Azure using DRBD/HeartbeatBuild HA Asterisk on Microsoft Azure using DRBD/Heartbeat
Build HA Asterisk on Microsoft Azure using DRBD/Heartbeat
 
Plone in the Cloud - an on-demand CMS hosted on Amazon EC2
Plone in the Cloud - an on-demand CMS hosted on Amazon EC2Plone in the Cloud - an on-demand CMS hosted on Amazon EC2
Plone in the Cloud - an on-demand CMS hosted on Amazon EC2
 
Introduction of openpear
Introduction of openpearIntroduction of openpear
Introduction of openpear
 

Andere mochten auch

Firebase: Totally Not Parse All Over Again (Unless It Is) (CocoaConf San Jose...
Firebase: Totally Not Parse All Over Again (Unless It Is) (CocoaConf San Jose...Firebase: Totally Not Parse All Over Again (Unless It Is) (CocoaConf San Jose...
Firebase: Totally Not Parse All Over Again (Unless It Is) (CocoaConf San Jose...Chris Adamson
 
Firebase: Totally Not Parse All Over Again (Unless It Is)
Firebase: Totally Not Parse All Over Again (Unless It Is)Firebase: Totally Not Parse All Over Again (Unless It Is)
Firebase: Totally Not Parse All Over Again (Unless It Is)Chris Adamson
 
Revenge of the 80s: Cut/Copy/Paste, Undo/Redo, and More Big Hits (CocoaConf C...
Revenge of the 80s: Cut/Copy/Paste, Undo/Redo, and More Big Hits (CocoaConf C...Revenge of the 80s: Cut/Copy/Paste, Undo/Redo, and More Big Hits (CocoaConf C...
Revenge of the 80s: Cut/Copy/Paste, Undo/Redo, and More Big Hits (CocoaConf C...Chris Adamson
 
Core Image: The Most Fun API You're Not Using (CocoaConf Columbus 2014)
Core Image: The Most Fun API You're Not Using (CocoaConf Columbus 2014)Core Image: The Most Fun API You're Not Using (CocoaConf Columbus 2014)
Core Image: The Most Fun API You're Not Using (CocoaConf Columbus 2014)Chris Adamson
 
Core Image: The Most Fun API You're Not Using, CocoaConf Atlanta, December 2014
Core Image: The Most Fun API You're Not Using, CocoaConf Atlanta, December 2014Core Image: The Most Fun API You're Not Using, CocoaConf Atlanta, December 2014
Core Image: The Most Fun API You're Not Using, CocoaConf Atlanta, December 2014Chris Adamson
 
Forward Swift 2017: Media Frameworks and Swift: This Is Fine
Forward Swift 2017: Media Frameworks and Swift: This Is FineForward Swift 2017: Media Frameworks and Swift: This Is Fine
Forward Swift 2017: Media Frameworks and Swift: This Is FineChris Adamson
 

Andere mochten auch (6)

Firebase: Totally Not Parse All Over Again (Unless It Is) (CocoaConf San Jose...
Firebase: Totally Not Parse All Over Again (Unless It Is) (CocoaConf San Jose...Firebase: Totally Not Parse All Over Again (Unless It Is) (CocoaConf San Jose...
Firebase: Totally Not Parse All Over Again (Unless It Is) (CocoaConf San Jose...
 
Firebase: Totally Not Parse All Over Again (Unless It Is)
Firebase: Totally Not Parse All Over Again (Unless It Is)Firebase: Totally Not Parse All Over Again (Unless It Is)
Firebase: Totally Not Parse All Over Again (Unless It Is)
 
Revenge of the 80s: Cut/Copy/Paste, Undo/Redo, and More Big Hits (CocoaConf C...
Revenge of the 80s: Cut/Copy/Paste, Undo/Redo, and More Big Hits (CocoaConf C...Revenge of the 80s: Cut/Copy/Paste, Undo/Redo, and More Big Hits (CocoaConf C...
Revenge of the 80s: Cut/Copy/Paste, Undo/Redo, and More Big Hits (CocoaConf C...
 
Core Image: The Most Fun API You're Not Using (CocoaConf Columbus 2014)
Core Image: The Most Fun API You're Not Using (CocoaConf Columbus 2014)Core Image: The Most Fun API You're Not Using (CocoaConf Columbus 2014)
Core Image: The Most Fun API You're Not Using (CocoaConf Columbus 2014)
 
Core Image: The Most Fun API You're Not Using, CocoaConf Atlanta, December 2014
Core Image: The Most Fun API You're Not Using, CocoaConf Atlanta, December 2014Core Image: The Most Fun API You're Not Using, CocoaConf Atlanta, December 2014
Core Image: The Most Fun API You're Not Using, CocoaConf Atlanta, December 2014
 
Forward Swift 2017: Media Frameworks and Swift: This Is Fine
Forward Swift 2017: Media Frameworks and Swift: This Is FineForward Swift 2017: Media Frameworks and Swift: This Is Fine
Forward Swift 2017: Media Frameworks and Swift: This Is Fine
 

Ähnlich wie Video Killed the Rolex Star (CocoaConf San Jose, November, 2015)

Formacion en movilidad: Conceptos de desarrollo en iOS (I)
Formacion en movilidad: Conceptos de desarrollo en iOS (I) Formacion en movilidad: Conceptos de desarrollo en iOS (I)
Formacion en movilidad: Conceptos de desarrollo en iOS (I) Mobivery
 
watchOS 2でゲーム作ってみた話
watchOS 2でゲーム作ってみた話watchOS 2でゲーム作ってみた話
watchOS 2でゲーム作ってみた話Kohki Miki
 
Voice That Matter 2010 - Core Audio
Voice That Matter 2010 - Core AudioVoice That Matter 2010 - Core Audio
Voice That Matter 2010 - Core AudioKevin Avila
 
Core Audio in iOS 6 (CocoaConf Portland, Oct. '12)
Core Audio in iOS 6 (CocoaConf Portland, Oct. '12)Core Audio in iOS 6 (CocoaConf Portland, Oct. '12)
Core Audio in iOS 6 (CocoaConf Portland, Oct. '12)Chris Adamson
 
Flash runtime on mobile
Flash runtime on mobileFlash runtime on mobile
Flash runtime on mobilehoward-wu
 
iOS におけるサウンド処理2015
iOS におけるサウンド処理2015iOS におけるサウンド処理2015
iOS におけるサウンド処理2015cocominap
 
Core Audio in iOS 6 (CocoaConf Chicago, March 2013)
Core Audio in iOS 6 (CocoaConf Chicago, March 2013)Core Audio in iOS 6 (CocoaConf Chicago, March 2013)
Core Audio in iOS 6 (CocoaConf Chicago, March 2013)Chris Adamson
 
SymfonyCon Madrid 2014 - Rock Solid Deployment of Symfony Apps
SymfonyCon Madrid 2014 - Rock Solid Deployment of Symfony AppsSymfonyCon Madrid 2014 - Rock Solid Deployment of Symfony Apps
SymfonyCon Madrid 2014 - Rock Solid Deployment of Symfony AppsPablo Godel
 
Core Audio: Don't Be Afraid to Play it LOUD! [360iDev, San Jose 2010]
Core Audio: Don't Be Afraid to Play it LOUD! [360iDev, San Jose 2010]Core Audio: Don't Be Afraid to Play it LOUD! [360iDev, San Jose 2010]
Core Audio: Don't Be Afraid to Play it LOUD! [360iDev, San Jose 2010]Chris Adamson
 
Alfresco Day Roma 2015: Infrastructure as Code with Chef-Alfresco
Alfresco Day Roma 2015: Infrastructure as Code with Chef-AlfrescoAlfresco Day Roma 2015: Infrastructure as Code with Chef-Alfresco
Alfresco Day Roma 2015: Infrastructure as Code with Chef-AlfrescoAlfresco Software
 
Creating Flash Content for Multiple Screens
Creating Flash Content for Multiple ScreensCreating Flash Content for Multiple Screens
Creating Flash Content for Multiple Screenspaultrani
 
Creating Hybrid mobile apps with YUI
Creating Hybrid mobile apps with YUICreating Hybrid mobile apps with YUI
Creating Hybrid mobile apps with YUIGonzalo Cordero
 
Android Audio & OpenSL
Android Audio & OpenSLAndroid Audio & OpenSL
Android Audio & OpenSLYoss Cohen
 
Using Adobe Gaming Tools for Education
Using Adobe Gaming Tools for EducationUsing Adobe Gaming Tools for Education
Using Adobe Gaming Tools for EducationJoseph Labrecque
 
JavaScript in 2015
JavaScript in 2015JavaScript in 2015
JavaScript in 2015Igor Laborie
 
HTML5 Multimedia Accessibility
HTML5 Multimedia AccessibilityHTML5 Multimedia Accessibility
HTML5 Multimedia Accessibilitybrucelawson
 
Thinking tts - Eric Floe
Thinking tts - Eric FloeThinking tts - Eric Floe
Thinking tts - Eric FloeEric Floe
 
iOSDC 2018 動画をなめらかに動かす技術
iOSDC 2018 動画をなめらかに動かす技術iOSDC 2018 動画をなめらかに動かす技術
iOSDC 2018 動画をなめらかに動かす技術Yuji Hato
 
node-webkit : Make a magic from your a desktop app to desktop app!
node-webkit : Make a magic from your a desktop app to desktop app!node-webkit : Make a magic from your a desktop app to desktop app!
node-webkit : Make a magic from your a desktop app to desktop app!욱진 양
 
Download and restrict video files in android app
Download and restrict video files in android appDownload and restrict video files in android app
Download and restrict video files in android appKaty Slemon
 

Ähnlich wie Video Killed the Rolex Star (CocoaConf San Jose, November, 2015) (20)

Formacion en movilidad: Conceptos de desarrollo en iOS (I)
Formacion en movilidad: Conceptos de desarrollo en iOS (I) Formacion en movilidad: Conceptos de desarrollo en iOS (I)
Formacion en movilidad: Conceptos de desarrollo en iOS (I)
 
watchOS 2でゲーム作ってみた話
watchOS 2でゲーム作ってみた話watchOS 2でゲーム作ってみた話
watchOS 2でゲーム作ってみた話
 
Voice That Matter 2010 - Core Audio
Voice That Matter 2010 - Core AudioVoice That Matter 2010 - Core Audio
Voice That Matter 2010 - Core Audio
 
Core Audio in iOS 6 (CocoaConf Portland, Oct. '12)
Core Audio in iOS 6 (CocoaConf Portland, Oct. '12)Core Audio in iOS 6 (CocoaConf Portland, Oct. '12)
Core Audio in iOS 6 (CocoaConf Portland, Oct. '12)
 
Flash runtime on mobile
Flash runtime on mobileFlash runtime on mobile
Flash runtime on mobile
 
iOS におけるサウンド処理2015
iOS におけるサウンド処理2015iOS におけるサウンド処理2015
iOS におけるサウンド処理2015
 
Core Audio in iOS 6 (CocoaConf Chicago, March 2013)
Core Audio in iOS 6 (CocoaConf Chicago, March 2013)Core Audio in iOS 6 (CocoaConf Chicago, March 2013)
Core Audio in iOS 6 (CocoaConf Chicago, March 2013)
 
SymfonyCon Madrid 2014 - Rock Solid Deployment of Symfony Apps
SymfonyCon Madrid 2014 - Rock Solid Deployment of Symfony AppsSymfonyCon Madrid 2014 - Rock Solid Deployment of Symfony Apps
SymfonyCon Madrid 2014 - Rock Solid Deployment of Symfony Apps
 
Core Audio: Don't Be Afraid to Play it LOUD! [360iDev, San Jose 2010]
Core Audio: Don't Be Afraid to Play it LOUD! [360iDev, San Jose 2010]Core Audio: Don't Be Afraid to Play it LOUD! [360iDev, San Jose 2010]
Core Audio: Don't Be Afraid to Play it LOUD! [360iDev, San Jose 2010]
 
Alfresco Day Roma 2015: Infrastructure as Code with Chef-Alfresco
Alfresco Day Roma 2015: Infrastructure as Code with Chef-AlfrescoAlfresco Day Roma 2015: Infrastructure as Code with Chef-Alfresco
Alfresco Day Roma 2015: Infrastructure as Code with Chef-Alfresco
 
Creating Flash Content for Multiple Screens
Creating Flash Content for Multiple ScreensCreating Flash Content for Multiple Screens
Creating Flash Content for Multiple Screens
 
Creating Hybrid mobile apps with YUI
Creating Hybrid mobile apps with YUICreating Hybrid mobile apps with YUI
Creating Hybrid mobile apps with YUI
 
Android Audio & OpenSL
Android Audio & OpenSLAndroid Audio & OpenSL
Android Audio & OpenSL
 
Using Adobe Gaming Tools for Education
Using Adobe Gaming Tools for EducationUsing Adobe Gaming Tools for Education
Using Adobe Gaming Tools for Education
 
JavaScript in 2015
JavaScript in 2015JavaScript in 2015
JavaScript in 2015
 
HTML5 Multimedia Accessibility
HTML5 Multimedia AccessibilityHTML5 Multimedia Accessibility
HTML5 Multimedia Accessibility
 
Thinking tts - Eric Floe
Thinking tts - Eric FloeThinking tts - Eric Floe
Thinking tts - Eric Floe
 
iOSDC 2018 動画をなめらかに動かす技術
iOSDC 2018 動画をなめらかに動かす技術iOSDC 2018 動画をなめらかに動かす技術
iOSDC 2018 動画をなめらかに動かす技術
 
node-webkit : Make a magic from your a desktop app to desktop app!
node-webkit : Make a magic from your a desktop app to desktop app!node-webkit : Make a magic from your a desktop app to desktop app!
node-webkit : Make a magic from your a desktop app to desktop app!
 
Download and restrict video files in android app
Download and restrict video files in android appDownload and restrict video files in android app
Download and restrict video files in android app
 

Mehr von Chris Adamson

Whatever Happened to Visual Novel Anime? (AWA/Youmacon 2018)
Whatever Happened to Visual Novel Anime? (AWA/Youmacon 2018)Whatever Happened to Visual Novel Anime? (AWA/Youmacon 2018)
Whatever Happened to Visual Novel Anime? (AWA/Youmacon 2018)Chris Adamson
 
Whatever Happened to Visual Novel Anime? (JAFAX 2018)
Whatever Happened to Visual Novel Anime? (JAFAX 2018)Whatever Happened to Visual Novel Anime? (JAFAX 2018)
Whatever Happened to Visual Novel Anime? (JAFAX 2018)Chris Adamson
 
Media Frameworks Versus Swift (Swift by Northwest, October 2017)
Media Frameworks Versus Swift (Swift by Northwest, October 2017)Media Frameworks Versus Swift (Swift by Northwest, October 2017)
Media Frameworks Versus Swift (Swift by Northwest, October 2017)Chris Adamson
 
Fall Premieres: Media Frameworks in iOS 11, macOS 10.13, and tvOS 11 (CocoaCo...
Fall Premieres: Media Frameworks in iOS 11, macOS 10.13, and tvOS 11 (CocoaCo...Fall Premieres: Media Frameworks in iOS 11, macOS 10.13, and tvOS 11 (CocoaCo...
Fall Premieres: Media Frameworks in iOS 11, macOS 10.13, and tvOS 11 (CocoaCo...Chris Adamson
 
CocoaConf Chicago 2017: Media Frameworks and Swift: This Is Fine
CocoaConf Chicago 2017: Media Frameworks and Swift: This Is FineCocoaConf Chicago 2017: Media Frameworks and Swift: This Is Fine
CocoaConf Chicago 2017: Media Frameworks and Swift: This Is FineChris Adamson
 
Glitch-Free A/V Encoding (CocoaConf Boston, October 2013)
Glitch-Free A/V Encoding (CocoaConf Boston, October 2013)Glitch-Free A/V Encoding (CocoaConf Boston, October 2013)
Glitch-Free A/V Encoding (CocoaConf Boston, October 2013)Chris Adamson
 
Core Audio in iOS 6 (CocoaConf San Jose, April 2013)
Core Audio in iOS 6 (CocoaConf San Jose, April 2013) Core Audio in iOS 6 (CocoaConf San Jose, April 2013)
Core Audio in iOS 6 (CocoaConf San Jose, April 2013) Chris Adamson
 
Core Audio in iOS 6 (CocoaConf DC, March 2013)
Core Audio in iOS 6 (CocoaConf DC, March 2013)Core Audio in iOS 6 (CocoaConf DC, March 2013)
Core Audio in iOS 6 (CocoaConf DC, March 2013)Chris Adamson
 
Mobile Movies with HTTP Live Streaming (CocoaConf DC, March 2013)
Mobile Movies with HTTP Live Streaming (CocoaConf DC, March 2013)Mobile Movies with HTTP Live Streaming (CocoaConf DC, March 2013)
Mobile Movies with HTTP Live Streaming (CocoaConf DC, March 2013)Chris Adamson
 
Core Audio Intro (Detroit Mobile City 2013)
Core Audio Intro (Detroit Mobile City 2013)Core Audio Intro (Detroit Mobile City 2013)
Core Audio Intro (Detroit Mobile City 2013)Chris Adamson
 
Objective-C Is Not Java
Objective-C Is Not JavaObjective-C Is Not Java
Objective-C Is Not JavaChris Adamson
 
Core Audio in iOS 6 (CocoaConf Raleigh, Dec. '12)
Core Audio in iOS 6 (CocoaConf Raleigh, Dec. '12)Core Audio in iOS 6 (CocoaConf Raleigh, Dec. '12)
Core Audio in iOS 6 (CocoaConf Raleigh, Dec. '12)Chris Adamson
 

Mehr von Chris Adamson (12)

Whatever Happened to Visual Novel Anime? (AWA/Youmacon 2018)
Whatever Happened to Visual Novel Anime? (AWA/Youmacon 2018)Whatever Happened to Visual Novel Anime? (AWA/Youmacon 2018)
Whatever Happened to Visual Novel Anime? (AWA/Youmacon 2018)
 
Whatever Happened to Visual Novel Anime? (JAFAX 2018)
Whatever Happened to Visual Novel Anime? (JAFAX 2018)Whatever Happened to Visual Novel Anime? (JAFAX 2018)
Whatever Happened to Visual Novel Anime? (JAFAX 2018)
 
Media Frameworks Versus Swift (Swift by Northwest, October 2017)
Media Frameworks Versus Swift (Swift by Northwest, October 2017)Media Frameworks Versus Swift (Swift by Northwest, October 2017)
Media Frameworks Versus Swift (Swift by Northwest, October 2017)
 
Fall Premieres: Media Frameworks in iOS 11, macOS 10.13, and tvOS 11 (CocoaCo...
Fall Premieres: Media Frameworks in iOS 11, macOS 10.13, and tvOS 11 (CocoaCo...Fall Premieres: Media Frameworks in iOS 11, macOS 10.13, and tvOS 11 (CocoaCo...
Fall Premieres: Media Frameworks in iOS 11, macOS 10.13, and tvOS 11 (CocoaCo...
 
CocoaConf Chicago 2017: Media Frameworks and Swift: This Is Fine
CocoaConf Chicago 2017: Media Frameworks and Swift: This Is FineCocoaConf Chicago 2017: Media Frameworks and Swift: This Is Fine
CocoaConf Chicago 2017: Media Frameworks and Swift: This Is Fine
 
Glitch-Free A/V Encoding (CocoaConf Boston, October 2013)
Glitch-Free A/V Encoding (CocoaConf Boston, October 2013)Glitch-Free A/V Encoding (CocoaConf Boston, October 2013)
Glitch-Free A/V Encoding (CocoaConf Boston, October 2013)
 
Core Audio in iOS 6 (CocoaConf San Jose, April 2013)
Core Audio in iOS 6 (CocoaConf San Jose, April 2013) Core Audio in iOS 6 (CocoaConf San Jose, April 2013)
Core Audio in iOS 6 (CocoaConf San Jose, April 2013)
 
Core Audio in iOS 6 (CocoaConf DC, March 2013)
Core Audio in iOS 6 (CocoaConf DC, March 2013)Core Audio in iOS 6 (CocoaConf DC, March 2013)
Core Audio in iOS 6 (CocoaConf DC, March 2013)
 
Mobile Movies with HTTP Live Streaming (CocoaConf DC, March 2013)
Mobile Movies with HTTP Live Streaming (CocoaConf DC, March 2013)Mobile Movies with HTTP Live Streaming (CocoaConf DC, March 2013)
Mobile Movies with HTTP Live Streaming (CocoaConf DC, March 2013)
 
Core Audio Intro (Detroit Mobile City 2013)
Core Audio Intro (Detroit Mobile City 2013)Core Audio Intro (Detroit Mobile City 2013)
Core Audio Intro (Detroit Mobile City 2013)
 
Objective-C Is Not Java
Objective-C Is Not JavaObjective-C Is Not Java
Objective-C Is Not Java
 
Core Audio in iOS 6 (CocoaConf Raleigh, Dec. '12)
Core Audio in iOS 6 (CocoaConf Raleigh, Dec. '12)Core Audio in iOS 6 (CocoaConf Raleigh, Dec. '12)
Core Audio in iOS 6 (CocoaConf Raleigh, Dec. '12)
 

Kürzlich hochgeladen

AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusZilliz
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontologyjohnbeverley2021
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Zilliz
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyKhushali Kathiriya
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamUiPathCommunity
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesrafiqahmad00786416
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...apidays
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfOrbitshub
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsNanddeep Nachan
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWERMadyBayot
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...Zilliz
 

Kürzlich hochgeladen (20)

AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 

Video Killed the Rolex Star (CocoaConf San Jose, November, 2015)

  • 1. Video Killed The Rolex Star Chris Adamson • @invalidname CocoaConf San Jose • November, 2015
  • 3. watchOS 2.0 • App Extension runs on watch, not on iPhone • New watchOS APIs for media playback and recording • Prepare yourself, they’re limited!
  • 4. From watchOS 2.0 Transition Guide You must implement your extension using the frameworks in the watchOS SDK instead of the iOS SDK. For any features not available in the provided frameworks, you must rely on your iPhone app to perform the corresponding task.
  • 5. From watchOS 2.0 Transition Guide Your extension now stores files and data on Apple Watch. Any data that is not part of your Watch app or WatchKit extension bundle must be fetched the network or from the companion iOS app running on the user’s iPhone. You cannot rely on a shared group container to exchange files with your iOS app. Fetching files involves transferring them wirelessly to Apple Watch.
  • 6. Media files. The Watch app handles audio and video playback in your app. If your WatchKit extension downloads media files from the network or the companion iOS app, you must place those files in a shared group container that is accessible to both your Watch app and WatchKit extension. For more information about managing media-related files, see Managing Your Media From watchOS 2.0 Transition Guide
  • 7. Media functionality • Video playback • Audio playback • Audio recording
  • 8. Video Playback • WKInterfaceMovie — Canned UI component for movie playback • WKInterfaceController — A/V features provided by primary UI controller class
  • 9. WKInterfaceMovie A WKInterfaceMovie object lets you play back video and audio content directly from your interface. A movie object displays a poster image with a play button on top of it. When the user taps the play button, WatchKit plays the movie in a modal interface.
  • 10.
  • 11. // WKInterfaceMovie.h // WatchKit WK_AVAILABLE_WATCHOS_ONLY(2.0) @interface WKInterfaceMovie : WKInterfaceObject - (void)setMovieURL:(NSURL *)URL; - (void)setVideoGravity:(WKVideoGravity)videoGravity; // default is WKVideoGravityResizeAspect - (void)setLoops:(BOOL)loops; - (void)setPosterImage:(nullable WKImage *)posterImage; @end
  • 12. Video Gravity • Conceptually identical to video gravity constants in AV Foundation • Resize — stretch pixels to fill container • Aspect (Fit) — honoring aspect ratio, scale to reach one set of bounds (top/bottom or right/left), then letter-/pillar-box • Aspect Fill — honoring aspect ratio, scale to reach both sets of bounds, allowing contents to be clipped if needed
  • 14. WKVideoGravity.
 ResizeAspect This is the default for WKInterfaceMovie.videoGravity
  • 17. WKInterfaceController • Media playback and recording methods provided by the base controller class • Can use these to play video whenever the app decides it’s time to do so
  • 18. - (void)presentMediaPlayerControllerWithURL:(NSURL *)URL
 options:(nullable NSDictionary *)options
 completion:(void(^)(BOOL didPlayToEnd,
 NSTimeInterval endTime,
 NSError * __nullable error))completion
 WK_AVAILABLE_WATCHOS_ONLY(2.0); - (void)dismissMediaPlayerController WK_AVAILABLE_WATCHOS_ONLY(2.0); options dictionary of presentMediaPlayerController takes WKVideoGravity key, uses the WKVideoGravity constants
  • 20. 1280x720 320x180 921,600 pixels 57,600 pixels 1/16 the size!
  • 21. Encoding Guidelines • Video Codec: H.264 High profile • Bitrate: 160 kbps, 30 frames/sec • Size: 320x180 (landscape), 208x260 (portrait) • Audio: 32 kbps
  • 24. WKInterfaceController Audio • Playback works just like video • Same recommendation for audio bitrate: 32 kbps • Audio playback always uses Bluetooth headphones/speakers if paired, otherwise internal speaker
  • 25. Audio Recording -(void)presentAudioRecordingControllerWithOutputURL:(NSURL *)URL
 preset:(WKAudioRecordingPreset)preset
 maximumDuration:(NSTimeInterval)maximumDuration
 actionTitle:(nullable NSString *)actionTitle
 completion:(void (^)(BOOL didSave,
 NSError * __nullable error))completion
 WK_AVAILABLE_WATCHOS_ONLY(2.0); - (void)dismissAudioRecordingController WK_AVAILABLE_WATCHOS_ONLY(2.0);
  • 26. presentAudioRecording
 ControllerWithOutputURL: • actionTitle — A string to use in an “end recording” button once audio capture is underway • preset — WKAudioRecording quality preset • NarrowBandSpeech (8 kHz sampling, 24 kbps AAC) • WideBandSpeech (16 kHz sampling, 32 kbps AAC) • HighQualityAudio (44.1 kHz sampling, 96 kbps AAC)
  • 27. Audio Player • “Headless” API for playing audio programmatically • Assumes app provides own UI, or doesn’t have one
  • 28. WKAudioFileAsset + (instancetype)assetWithURL:(NSURL *)URL; + (instancetype)assetWithURL:(NSURL *)URL
 title:(nullable NSString *)title
 albumTitle:(nullable NSString *)albumTitle
 artist:(nullable NSString *)artist;
  • 29. WKAudioFilePlayerItem • status — .Unknown, .ReadyToPlay, .Failed • Notifications — Time jumped, Played to End, Failed to Play to End + (WKAudioFilePlayerItem *)playerItemWithAsset:(WKAudioFileAsset *)asset; @property (nonatomic, readonly) WKAudioFileAsset *asset; @property (nonatomic, readonly) WKAudioFilePlayerItemStatus status; @property (nonatomic, readonly, nullable) NSError *error; @property (nonatomic, readonly) NSTimeInterval currentTime;
  • 30. WKAudioFilePlayer + (instancetype)playerWithPlayerItem:
 (WKAudioFilePlayerItem *)item; - (void)play; - (void)pause; - (void)replaceCurrentItemWithPlayerItem:
 (nullable WKAudioFilePlayerItem *)item; @property(nonatomic, readonly, nullable) WKAudioFilePlayerItem *currentItem; @property (nonatomic, readonly) WKAudioFilePlayerStatus status; @property (nonatomic, readonly, nullable) NSError *error; @property (nonatomic) float rate; @property (nonatomic, readonly) NSTimeInterval currentTime;
  • 31. WKAudioFileQueuePlayer @interface WKAudioFileQueuePlayer : WKAudioFilePlayer + (instancetype)queuePlayerWithItems:
 (NSArray<WKAudioFilePlayerItem *> *)items; - (void)advanceToNextItem; - (void)appendItem:(WKAudioFilePlayerItem *)item; - (void)removeItem:(WKAudioFilePlayerItem *)item; - (void)removeAllItems; @property(nonatomic, readonly) NSArray<WKAudioFilePlayerItem *> *items; @end
  • 33. Video Killed The Rolex Star Chris Adamson • @invalidname CocoaConf San Jose • November, 2015 Slides available at slideshare.net/invalidname Code (eventually) at github.com/invalidname
  • 34. Now wait a darn minute!
  • 35.
  • 36. AVFoundation, Core Image, and Core Audio are huge and complex, but required for lots of app types. Will any audio, video, or image APIs be available? Will they only be possible through limited, high-level interfaces? http://www.marco.org/2015/05/28/watch-sdk-questions
  • 37. Available System Technologies Extensions built specifically for watchOS 2 have access to the following system frameworks: ClockKit Contacts Core Data Core Foundation Core Graphics Core Location Core Motion EventKit Foundation HealthKit HomeKit ImageIO MapKit Mobile Core Services PassKit Security Watch Connectivity WatchKit Notice the absence of AV Foundation, Core Audio, Core Media, and Core Video
  • 38. From watchOS 2.0 Transition Guide You must implement your extension using the frameworks in the watchOS SDK instead of the iOS SDK. For any features not available in the provided frameworks, you must rely on your iPhone app to perform the corresponding task.
  • 40.
  • 41. AUGraph AUFilePlayer AURemoteIO AVAudioEngine is conceptually similar, but can’t do a step we need later, so this is the Core Audio approach
  • 44. OSStatus timeShift(NSURL *inSourceURL, NSURL *inDestinationURL, float inSpeed) { OSStatus err = noErr; // crate graph AUGraph auGraph; err = NewAUGraph(&auGraph); if (err != noErr) {goto fail;} // goto fail, go directly to fail... AudioComponentDescription compDesc = {0}; // file player NSLog (@"Making AUFilePlayer"); AUNode filePlayerNode; AudioUnit filePlayerUnit; compDesc.componentType = kAudioUnitType_Generator; compDesc.componentSubType = kAudioUnitSubType_AudioFilePlayer; compDesc.componentManufacturer = kAudioUnitManufacturer_Apple; err = AUGraphAddNode(auGraph, &compDesc, &filePlayerNode); if (err != noErr) {goto fail;} // goto fail, go directly to fail... err = AUGraphNodeInfo(auGraph, filePlayerNode, NULL, &filePlayerUnit); if (err != noErr) {goto fail;} // goto fail, go directly to fail... // AUNewTimePitch NSLog (@"Making AUNewTimePitch"); AUNode timePitchNode; AudioUnit timePitchUnit; memset(&compDesc, 0, sizeof(compDesc)); compDesc.componentType = kAudioUnitType_FormatConverter; compDesc.componentSubType = kAudioUnitSubType_NewTimePitch; compDesc.componentManufacturer = kAudioUnitManufacturer_Apple; // and another 100 lines or so of this!
  • 45. ?
  • 46. Watch Connectivity The Watch Connectivity framework (WatchConnectivity.framework) provides a two-way communications conduit between an iOS app and a WatchKit extension on a paired Apple Watch. Apps use this framework to pass files and data back and forth. Most transfers happen in the background when the receiving app is inactive. When the app wakes up, it is notified of any data that arrived while it was inactive. Live communication is also possible when both apps are active.
  • 48. Phone: Activate WCSession if WCSession.isSupported() { WCSession.defaultSession().delegate = self WCSession.defaultSession().activateSession() NSLog ("iPhone WCSession ready") }
  • 49. Watch: Activate WCSession if WCSession.isSupported() { WCSession.defaultSession().delegate = self WCSession.defaultSession().activateSession() NSLog ("Watch WCSession ready") }
  • 50. Phone: transfer file let transfer = WCSession.defaultSession().transferFile(url, metadata: nil) NSLog ("transferring: (transfer)") //MARK: WatchConnectivity delegate func session(session: WCSession, didFinishFileTransfer fileTransfer: WCSessionFileTransfer, error: NSError?) { NSLog ("didFinishFileTransfer: (fileTransfer), error: (error)") }
  • 51. Watch: receive file func session(session: WCSession, didReceiveFile file: WCSessionFile) { NSLog ("didReceiveFile: (file)") let docsURL = NSFileManager.defaultManager().URLsForDirectory( NSSearchPathDirectory.DocumentDirectory, inDomains: NSSearchPathDomainMask.UserDomainMask).first let storageURL = docsURL?.URLByAppendingPathComponent( file.fileURL.lastPathComponent!) do { try NSFileManager.defaultManager().copyItemAtURL(file.fileURL, toURL: storageURL!) pushControllerWithName("player", context: storageURL) } catch let error as NSError { NSLog ("copy error: (error)") } } file: If you want to keep the file referenced by this parameter, you must move it synchronously to a new location during your implementation of this method. If you do not move the file, the system deletes it after this method returns.
  • 54.
  • 55.
  • 57. Export Preset Names for Apple Devices You use these export options to produce files that can be played on the specific Apple devices. Declaration SWIFT let AVAssetExportPresetAppleM4VCellular: String let AVAssetExportPresetAppleM4ViPod: String let AVAssetExportPresetAppleM4V480pSD: String let AVAssetExportPresetAppleM4VAppleTV: String let AVAssetExportPresetAppleM4VWiFi: String let AVAssetExportPresetAppleM4V720pHD: String let AVAssetExportPresetAppleM4V1080pHD: String let AVAssetExportPresetAppleProRes422LPCM: String
  • 58. AVAssetWriter • Low-level access for writing media files • Allows you to specify output size, encoding settings, bitrate, etc. • Requires you to write each CMSampleBuffer individually
  • 59. AVAssetWriterInput SWIFT let AVVideoCodecKey: String let AVVideoCodecH264: String let AVVideoCodecJPEG: String let AVVideoCodecAppleProRes4444: String let AVVideoCodecAppleProRes422: String let AVVideoWidthKey: String let AVVideoHeightKey: String let AVVideoCompressionPropertiesKey: String let AVVideoAverageBitRateKey: String let AVVideoQualityKey: String let AVVideoMaxKeyFrameIntervalKey: String let AVVideoProfileLevelKey: String let AVVideoProfileLevelH264Baseline30: String let AVVideoProfileLevelH264Baseline31: String let AVVideoProfileLevelH264Baseline41: String let AVVideoProfileLevelH264Main30: String let AVVideoProfileLevelH264Main31: String let AVVideoProfileLevelH264Main32: String let AVVideoProfileLevelH264Main41: String let AVVideoProfileLevelH264High40: String let AVVideoProfileLevelH264High41: String let AVVideoPixelAspectRatioKey: String let AVVideoPixelAspectRatioHorizontalSpacingKey: String let AVVideoPixelAspectRatioVerticalSpacingKey: String let AVVideoCleanApertureKey: String let AVVideoCleanApertureWidthKey: String let AVVideoCleanApertureHeightKey: String let AVVideoCleanApertureHorizontalOffsetKey: String let AVVideoCleanApertureVerticalOffsetKey: String Video Settings These constants define dictionary keys for configuring video compression and compression settings for video assets. - initWithMediaType:outputSettings:sourceFormatHint:
  • 60. AVAssetReader Output AVAssetReader Output AVAssetWriter Input AVAssetWriter Input Audio path (output settings to change bitrate) Video path (output settings to change size, encoding, bitrate)
  • 61. Takeaways • Basic support for file-based audio/video playback and audio recording • Playback files are either in your bundle or downloaded by your iOS app + extension • Any downloading or media processing needs to be performed on your iPhone, then sent to watch extension/app via Watch Connectivity
  • 62. Video Killed The Rolex Star Chris Adamson • @invalidname CocoaConf San Jose • November, 2015 Slides will be at slideshare.net/invalidname Code (eventually, maybe) at github.com/invalidname