SlideShare ist ein Scribd-Unternehmen logo
1 von 62
Downloaden Sie, um offline zu lesen
Stupid Video Tricks
Chris Adamson • @invalidname
CocoaConf DC • March, 2014
AV Foundation
• Framework for working with time-based media
• Audio, video, timed text (captions / subtitles),
timecode
• iOS 4.0 and up, Mac OS X 10.7 (Lion) and up
• Replacing QuickTime on Mac
Ordinary AV Foundation stuff
• Playback: AVAsset + AVPlayer
• Capture to file: AVCaptureSession +
AVCaptureDeviceInput +
AVCaptureMovieFileOutput
• Editing: AVComposition + AVExportSession
But Why Be Ordinary?
http://www.crunchyroll.com/my-ordinary-life
Introductory Trick
• AVPlayerLayer and
AVCaptureVideoPreviewLayer are subclasses of
CALayer
• We can do lots of neat things with CALayers
Demo
Make an AVPlayerLayer
self.player = [AVPlayer playerWithPlayerItem:
[AVPlayerItem playerItemWithAsset:self.asset]];
self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
self.playerLayer.videoGravity = AVLayerVideoGravityResizeAspect;
[self.playerView.layer addSublayer:self.playerLayer];
self.playerLayer.frame = self.playerView.bounds;
Animate the layer
CABasicAnimation *animateRotation;
animateRotation = [CABasicAnimation animationWithKeyPath:@"transform"];
CATransform3D layerTransform = self.playerLayer.transform;
layerTransform = CATransform3DRotate(layerTransform, M_PI, 1.0, 1.0, 0.0);
animateRotation.toValue = [NSValue valueWithCATransform3D:layerTransform];
animateRotation.duration = 2.0;
animateRotation.removedOnCompletion = NO;
animateRotation.fillMode = kCAFillModeForwards;
animateRotation.repeatCount = 1000;
animateRotation.cumulative = YES;
[self.playerLayer addAnimation:animateRotation forKey:@"transform"];
Going Deeper
http://www.crunchyroll.com/angel-beats
AV Foundation
Core Audio Core Media
Video Toolbox
Core Video
AV Foundation
Core Audio Core Media
Video Toolbox
Core Video
AV Foundation
Core Audio Core Media
Video Toolbox
Core Video
Core Media
Core Media
• Opaque types to represent time: CMTime,
CMTimeRange
• Opaque types to represent media samples and their
contents: CMSampleBuffer, CMBlockBuffer,
CMFormatDescription
CMSampleBuffer
• Provides timing information for one or more samples:
when does this play and for how long?
• Contains either
• CVImageBuffer – visual data (video frames)
• CMBlockBuffer — arbitrary data (sound, subtitles,
timecodes)
Use & Abuse of
CMSampleBuffers
• AVCaptureDataOutput provides CMSampleBuffers
in sample delegate callback
• AVAssetReader provides CMSampleBuffers read
from disk
• AVAssetWriter accepts CMSampleBuffers to write
to disk
Demo
How the Heck Does that
Work?
• Movies have tracks, tracks have media, media have
sample data
• All contents of a QuickTime file are defined in the
QuickTime File Format documentation
Subtitle Sample Data
Subtitle sample data consists of a 16-‐bit word that specifies the length (number of bytes) of the subtitle text,
followed by the subtitle text and then by optional sample extensions. The subtitle text is Unicode text, encoded
either as UTF-‐8 text or UTF-‐16 text beginning with a UTF-‐16 BYTE ORDER MARK ('uFEFF') in big or little endian
order. There is no null termination for the text.
Following the subtitle text, there may be one or more atoms containing additional information for selecting
and drawing the subtitle.
Table 4-‐12 (page 203) lists the currently defined subtitle sample extensions.
Table 4-12 Subtitle sample extensions
DescriptionSubtitle
sample
extension
The presence of this atom indicates that the sample contains a forced subtitle. This
extension has no data.
Forced subtitles are shown automatically when appropriate without any interaction
from the user. If any sample contains a forced subtitle, the Some Samples Are Forced
(0x40000000) flag must also be set in the display flags.
Consider an example where the primary language of the content is English, but the
user has chosen to listen to a French dub of the audio. If a scene in the video displays
something in English that is important to the plot or the content (such as a newspaper
headline), a forced subtitle displays the content translated into French. In this case, the
subtitle is linked (“forced”) to the French language sound track.
If this atom is not present, the subtitle is typically simply a translation of the audio
content, which a user can choose to display or hide.
'frcd'
Style information for the subtitle. This atom allows you to override the default style in
the sample description or to define more than one style within a sample. See “Subtitle
Style Atom” (page 204).
'styl'
Override of the default text box for this sample. Used only if the 0x20000000 display
flag is set in the sample description and, in that case, only the top is considered. Even
so, all fields should be set as though they are considered. See “Text Box atom” (page
205).
'tbox'
Text wrap. Set the one-‐byte payload to 0x00 for no wrapping or 0x01 for automatic
soft wrapping.
'twrp'
Media Data Atom Types
Subtitle Media
2014-‐02-‐11 | Copyright © 2004, 2014 Apple Inc. All Rights Reserved.
203
Subtitle Sample Data!
Subtitle sample data consists of a 16-bit word that
specifies the length (number of bytes) of the subtitle text,
followed by the subtitle text and then by optional sample
extensions. The subtitle text is Unicode text, encoded
either as UTF-8 text or UTF-16 text beginning with a
UTF-16 BYTE ORDER MARK ('uFEFF') in big or little
endian order. There is no null termination for the text.!
Following the subtitle text, there may be one or more
atoms containing additional information for selecting and
drawing the subtitle.!
I Iz In Ur Subtitle Track…
AVAssetReaderTrackOutput *subtitleTrackOutput =
[AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:subtitleTracks[0]
outputSettings:nil];
!
// ...
while (reading) {
CMSampleBufferRef sampleBuffer = [subtitleTrackOutput copyNextSampleBuffer];
if (sampleBuffer == NULL) {
AVAssetReaderStatus status = subtitleReader.status;
if ((status == AVAssetReaderStatusCompleted) ||
(status == AVAssetReaderStatusFailed) ||
(status == AVAssetReaderStatusCancelled)) {
reading = NO;
NSLog (@"ending with reader status %d", status);
}
} else {
CMTime presentationTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer) ;
CMTime duration = CMSampleBufferGetDuration(sampleBuffer);
…Readin Ur CMBlockBuffers
CMBlockBufferRef blockBuffer = CMSampleBufferGetDataBuffer(sampleBuffer);
size_t dataSize =CMBlockBufferGetDataLength(blockBuffer);
if (dataSize > 0) {
UInt8* data = malloc(dataSize);
OSStatus cmErr = CMBlockBufferCopyDataBytes (blockBuffer,
0,
dataSize,
data);
Subtitle Summary
• AVAssetReaderOutput provides CMSampleBuffers
• Get timing info with
CMSampleBufferGetPresentationTimestamp()
and CMSampleGetDuration()
• Get raw data with CMBlockBufferGet…() functions
• Have at it
Audio
http://indignation.deviantart.com/art/Hatsune-Miku-headphones-254724145
AV Foundation
Core Audio Core Media
Video Toolbox
Core Video
Core Audio Core Media
• Reading:
CMSampleBufferGetAudioBufferListWithRetain
edBlockBuffer(),
CMSampleBufferGetAudioStreamPacketDescript
ions()
• Writing:
CMSampleBufferSetDataBufferFromAudioBuffer
List(),
CMAudioSampleBufferCreateWithPacketDescrip
tions()
Core Audio Core Media
• Reading:
CMSampleBufferGetAudioBufferListWithRetain
edBlockBuffer(),
CMSampleBufferGetAudioStreamPacketDescript
ions()
• Writing:
CMSampleBufferSetDataBufferFromAudioBuffer
List(),
CMAudioSampleBufferCreateWithPacketDescrip
tions()
Core Audio Core Media
Potential Uses
• Run captured / read-in audio through effects in an
AUGraph
• See “AVCaptureAudioDataOutput To AudioUnit”
examples (iOS & OS X) from WWDC 2012
• May make more sense for audio-oriented apps to do
capture / file reads entirely from Core Audio
Video
http://www.crunchyroll.com/angel-beats
AV Foundation
Core Audio Core Media
Video Toolbox
Core Video
Core Media Core Video
• CMSampleBuffers provide CVImageBuffers
• Two sub-types: CVPixelBufferRef,
CVOpenGLESTextureRef
• Pixel buffers allow us to work with bitmaps, via
CVPixelBufferGetBaseAddress()
• Note: Must wrap calls with
CVPixelBufferLockBaseAddress(),
CVPixelBufferUnlockBaseAddress()
Core Media Core Video
Use & Abuse of
CVImageBuffers
• Can be used to create Core Image CIImages
• iOS: -[CIImage imageWithCVPixelBuffer:]
• OS X: -[CIImage imageWithCVImageBuffer:]
• CIImages can be used to do lots of stuff…
Demo
Recipe
• Create CIContext from EAGLContext
• Create CIFilter
• During capture callback
• Convert pixel buffer to CIImage
• Run through filter
• Draw to CIContext
Set Up GLKView
if (! self.glkView.context.API != kEAGLRenderingAPIOpenGLES2) {
EAGLContext *eagl2Context = [[EAGLContext alloc]
initWithAPI:kEAGLRenderingAPIOpenGLES2];
self.glkView.context = eagl2Context;
}
self.glContext = self.glkView.context;
// we'll do the updating, thanks
self.glkView.enableSetNeedsDisplay = NO;
Make CIContext
// make CIContext from GL context, clearing out default color space
self.ciContext = [CIContext contextWithEAGLContext:self.glContext
options:@{kCIContextWorkingColorSpace :
[NSNull null]} ];
[self.glkView bindDrawable];
// from Core Image Fun House:
_glkDrawBounds = CGRectZero;
_glkDrawBounds.size.width = self.glkView.drawableWidth;
_glkDrawBounds.size.height = self.glkView.drawableHeight;
See also iOS Core Image Fun House from WWDC 2013
Get RGB in Capture Delegate
self.videoDataOutput = [[AVCaptureVideoDataOutput alloc] init];
[self.videoDataOutput setSampleBufferDelegate:self
queue:self.videoDataOutputQueue];
[self.captureSession addOutput: self.videoDataOutput];
NSDictionary *videoSettings = @{
(id) kCVPixelBufferPixelFormatTypeKey:
@(kCVPixelFormatType_32BGRA)};
[self.videoDataOutput setVideoSettings:videoSettings];
Note: 32BGRA and two flavors of 4:2:0 YCbCr are the only valid
pixel formats for video capture on iOS
Create CIFilter
self.pixellateFilter = [CIFilter filterWithName:@"CIPixellate"];
[self.pixellateFilter setValue:[CIVector vectorWithX:100.0 Y:100.0]
forKey:@"inputCenter"];
[self setPixellateFilterScale:self.pixellationScaleSlider.value];
Set CIFilter Params
- (IBAction)handleScaleSliderValueChanged:(UISlider*) sender {
[self setPixellateFilterScale:sender.value];
}
!
-(void) setPixellateFilterScale: (CGFloat) scale {
[self.pixellateFilter setValue:[NSNumber numberWithFloat:scale]
forKey:@"inputScale"];
}
Callback: Apply Filter
CVImageBufferRef cvBuffer =
CMSampleBufferGetImageBuffer(sampleBuffer);
CVPixelBufferLockBaseAddress(cvBuffer,0);
CIImage *bufferCIImage = [CIImage imageWithCVPixelBuffer:cvBuffer];
!
[self.pixellateFilter setValue:bufferCIImage
forKey:kCIInputImageKey];
bufferCIImage = [self.pixellateFilter
valueForKey:kCIOutputImageKey];
Callback: Draw to GLKView
[self.glkView bindDrawable];
if (self.glContext != [EAGLContext currentContext]) {
[EAGLContext setCurrentContext: self.glContext];
}
// drawing code here is from WWDC 2013 iOS Core Image Fun House
// clear eagl view to grey
glClearColor(0.5, 0.5, 0.5, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
// set the blend mode to "source over" so that CI will use that
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
CGRect drawRect = bufferCIImage.extent;
[self.ciContext drawImage:bufferCIImage
inRect:self.glkDrawBounds
fromRect:drawRect];
[self.glkView display];
CVPixelBufferUnlockBaseAddress(cvBuffer, 0);
Recap
CVPixelBuffer CIImage CIImage
from
camera
CIFilter
CIContext
-[CIContext
drawImage:
fromRect:
inRect:]
(OpenGL
drawing)
+[CIImage
imageWith
CVPixelBuff
er:]
Recap
CVPixelBuffer CIImage CIImage
from
camera
CIFilter
CIContext
-[CIContext
drawImage:
fromRect:
inRect:]
CVPixelBuffer
(optional)
AVAsset
Writer
Output(OpenGL
drawing)
+[CIImage
imageWith
CVPixelBuff
er:]
By the way…
There are lots of CIFilters
CICategoryBlur
! ! CIBoxBlur
! ! CIDiscBlur
! ! CIGaussianBlur
! ! CIMedianFilter
! ! CIMotionBlur
! ! CINoiseReduction
! ! CIZoomBlur
CICategoryColorAdjust
ment
! ! CIColorClamp
! ! CIColorControls
! ! CIColorMatrix
! ! CIColorPolynomial
! ! CIExposureAdjust
! ! CIGammaAdjust
! ! CIHueAdjust
! !
CILinearToSRGBToneCurv
e
! !
CISRGBToneCurveToLinea
r
! ! CITemperatureAndTint
! ! CIToneCurve
! ! CIVibrance
! ! CIWhitePointAdjust
CICategoryColorEffect
! ! CIColorCrossPolynomial
! ! CIColorCube
! !
CIColorCubeWithColorSp
ace
! ! CIColorInvert
! ! CIColorMap
! ! CIColorMonochrome
! ! CIColorPosterize
! ! CIFalseColor
! ! CIMaskToAlpha
! ! CIMaximumComponent
! ! CIMinimumComponent
! ! CIPhotoEffectChrome
! ! CIPhotoEffectFade
! ! CIPhotoEffectInstant
! ! CIPhotoEffectMono
! ! CIPhotoEffectNoir
! ! CIPhotoEffectProcess
! ! CIPhotoEffectTonal
! ! CIPhotoEffectTransfer
! ! CISepiaTone
! ! CIVignette
! ! CIVignetteEffect
CICategoryComposite
Operation
! ! CIAdditionCompositing
! ! CIColorBlendMode
! ! CIColorBurnBlendMode
! ! CIColorDodgeBlendMode
! ! CIDarkenBlendMode
! ! CIDifferenceBlendMode
! ! CIExclusionBlendMode
! ! CIHardLightBlendMode
! ! CIHueBlendMode
! ! CILightenBlendMode
! ! CILuminosityBlendMode
! ! CIMaximumCompositing
! ! CIMinimumCompositing
! ! CIMultiplyBlendMode
! ! CIMultiplyCompositing
! ! CIOverlayBlendMode
! ! CISaturationBlendMode
! ! CIScreenBlendMode
! ! CISoftLightBlendMode
! !
CISourceAtopCompositin
g
! ! CISourceInCompositing
! ! CISourceOutCompositing
! !
CISourceOverCompositin
g
CICategoryDistortionE
ffect
! ! CIBumpDistortion
! ! CIBumpDistortionLinear
! !
CICircleSplashDistorti
on
! ! CICircularWrap
! ! CIDroste
! !
CIDisplacementDistorti
on
! ! CIGlassDistortion
! ! CIGlassLozenge
! ! CIHoleDistortion
! ! CILightTunnel
! ! CIPinchDistortion
! ! CIStretchCrop
! ! CITorusLensDistortion
! ! CITwirlDistortion
! ! CIVortexDistortion
CICategoryGenerator
! CICheckerboardGenerator
! !
CIConstantColorGenerat
or
! !
CILenticularHaloGenera
tor
! ! CIQRCodeGenerator
! ! CIRandomGenerator
! ! CIStarShineGenerator
! ! CIStripesGenerator
! ! CISunbeamsGenerator
CICategoryGeometryA
djustment
! ! CIAffineTransform
! ! CICrop
! !
CILanczosScaleTransfor
m
! ! CIPerspectiveTransform
! !
CIPerspectiveTransform
WithExtent
! ! CIStraightenFilter
CICategoryGradient
! ! CIGaussianGradient
! ! CILinearGradient
! ! CIRadialGradient
! ! CISmoothLinearGradient
CICategoryHalftoneEff
ect
Demo
CIColorCube
Maps colors from one RGB “cube” to another
http://en.wikipedia.org/wiki/RGB_color_space
Using CIColorCube
CIColorCube maps green(-ish) colors to 0.0 alpha,
all other colors pass through
CISourceOverCompositing
inputBackgroundImage inputImage
outputImage
CIColorCube Data
const unsigned int size = 64;
size_t cubeDataSize = size * size * size * sizeof (float) * 4;
float *keyCubeData = (float *)malloc (cubeDataSize);
float rgb[3], hsv[3], *keyC = keyCubeData;
// Populate cube with a simple gradient going from 0 to 1
for (int z = 0; z < size; z++){
rgb[2] = ((double)z)/(size-1); // Blue value
for (int y = 0; y < size; y++){
rgb[1] = ((double)y)/(size-1); // Green value
for (int x = 0; x < size; x ++){
rgb[0] = ((double)x)/(size-1); // Red value
!
// Convert RGB to HSV
// You can find publicly available rgbToHSV functions on the Internet
!
RGBtoHSV(rgb[0], rgb[1], rgb[2],
&hsv[0], &hsv[1], &hsv[2]);
!
// RGBtoHSV uses 0 to 360 for hue, while UIColor (used above) uses 0 to 1.
hsv[0] /= 360.0;
// Use the hue value to determine which to make transparent
// The minimum and maximum hue angle depends on
// the color you want to remove
bool keyed = (hsv[0] > minHueAngle && hsv[0] < maxHueAngle) &&
(hsv[1] > minSaturation && hsv[1] < maxSaturation) &&
(hsv[2] > minBrightness && hsv[2] < maxBrightness);
float alpha = keyed ? 0.0f : 1.0f;
// re-calculate c pointer
keyC = (((z * size * size) + (y * size) + x) * sizeof(float)) + keyCubeData;
// Calculate premultiplied alpha values for the cube
keyC[0] = rgb[0] * alpha;
keyC[1] = rgb[1] * alpha;
keyC[2] = rgb[2] * alpha;
keyC[3] = alpha;
}
}
}
See “Chroma Key Filter Recipe” in Core Image Programming Guide
Create CIColorCube from
mapping data
// Create memory with the cube data
NSData *data = [NSData dataWithBytesNoCopy:keyCubeData
length:cubeDataSize
freeWhenDone:YES];
self.colorCubeFilter = [CIFilter filterWithName:@"CIColorCube"];
[self.colorCubeFilter setValue:[NSNumber numberWithInt:size]
forKey:@"inputCubeDimension"];
// Set data for cube
[self.colorCubeFilter setValue:data forKey:@"inputCubeData"];
Create
CISourceOverCompositing
// source over filter
self.sourceOverFilter = [CIFilter filterWithName:
@"CISourceOverCompositing"];
CIImage *backgroundCIImage = [CIImage imageWithCGImage:
self.backgroundImage.CGImage];
[self.sourceOverFilter setValue:backgroundCIImage
forKeyPath:@"inputBackgroundImage"];
Apply Filters in Delegate
Callback
CIImage *bufferCIImage = [CIImage imageWithCVPixelBuffer:
cvBuffer];
[self.colorCubeFilter setValue:bufferCIImage
forKey:kCIInputImageKey];
CIImage *keyedCameraImage = [self.colorCubeFilter valueForKey:
kCIOutputImageKey];
[self.sourceOverFilter setValue:keyedCameraImage
forKeyPath:kCIInputImageKey];
CIImage *compositedImage = [self.sourceOverFilter valueForKeyPath:
kCIOutputImageKey];
Then draw compositedImage to CIContext as before
More Fun with Filters
• Alpha Matte: Use CIColorCube to map green to white
(or transparent), everything else to black
• Can then use this with other filters to do edge work
on the “foreground” object
• Be sure that any filters you use are of category
CICategoryVideo.
More Fun With CIContexts
• Can write effected pixels to a movie file with
AVAssetWriterOutput
• Use base address of CIContext to create a new
CVPixelBuffer, use this and timing information to
create a CMSampleBuffer
• AVAssetWriterInputPixelBufferAdaptor makes this
slightly easier
Recap
• Most good tricks start with CMSampleBuffers
• Audio: convert to Core Audio types
• Video: convert to CIImage
• Other: get CMBlockBuffer and parse by hand
Further Info
and http://devforums.apple.com/
Q&A
Slides at http://www.slideshare.net/invalidname/
See comments there for link to source code
!
invalidname [at] gmail.com
@invalidname (Twitter, app.net)
http://www.subfurther.com/blog

Weitere ähnliche Inhalte

Andere mochten auch

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
 
Video Killed the Rolex Star (CocoaConf Columbus, July 2015)
Video Killed the Rolex Star (CocoaConf Columbus, July 2015)Video Killed the Rolex Star (CocoaConf Columbus, July 2015)
Video Killed the Rolex Star (CocoaConf Columbus, July 2015)Chris Adamson
 
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
 
Building A Streaming Apple TV App (CocoaConf San Jose, Nov 2016)
Building A Streaming Apple TV App (CocoaConf San Jose, Nov 2016)Building A Streaming Apple TV App (CocoaConf San Jose, Nov 2016)
Building A Streaming Apple TV App (CocoaConf San Jose, Nov 2016)Chris Adamson
 
Stupid Video Tricks, CocoaConf Seattle 2014
Stupid Video Tricks, CocoaConf Seattle 2014Stupid Video Tricks, CocoaConf Seattle 2014
Stupid Video Tricks, CocoaConf Seattle 2014Chris Adamson
 
Video Killed the Rolex Star (CocoaConf San Jose, November, 2015)
Video Killed the Rolex Star (CocoaConf San Jose, November, 2015)Video Killed the Rolex Star (CocoaConf San Jose, November, 2015)
Video Killed the Rolex Star (CocoaConf San Jose, November, 2015)Chris Adamson
 
Introduction to the Roku SDK
Introduction to the Roku SDKIntroduction to the Roku SDK
Introduction to the Roku SDKChris 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
 
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
 
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 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 (12)

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)
 
Video Killed the Rolex Star (CocoaConf Columbus, July 2015)
Video Killed the Rolex Star (CocoaConf Columbus, July 2015)Video Killed the Rolex Star (CocoaConf Columbus, July 2015)
Video Killed the Rolex Star (CocoaConf Columbus, July 2015)
 
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...
 
Building A Streaming Apple TV App (CocoaConf San Jose, Nov 2016)
Building A Streaming Apple TV App (CocoaConf San Jose, Nov 2016)Building A Streaming Apple TV App (CocoaConf San Jose, Nov 2016)
Building A Streaming Apple TV App (CocoaConf San Jose, Nov 2016)
 
Stupid Video Tricks, CocoaConf Seattle 2014
Stupid Video Tricks, CocoaConf Seattle 2014Stupid Video Tricks, CocoaConf Seattle 2014
Stupid Video Tricks, CocoaConf Seattle 2014
 
Video Killed the Rolex Star (CocoaConf San Jose, November, 2015)
Video Killed the Rolex Star (CocoaConf San Jose, November, 2015)Video Killed the Rolex Star (CocoaConf San Jose, November, 2015)
Video Killed the Rolex Star (CocoaConf San Jose, November, 2015)
 
Introduction to the Roku SDK
Introduction to the Roku SDKIntroduction to the Roku SDK
Introduction to the Roku SDK
 
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)
 
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)
 
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 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 AV Foundation Video Tricks

Voice That Matter 2010 - Core Audio
Voice That Matter 2010 - Core AudioVoice That Matter 2010 - Core Audio
Voice That Matter 2010 - Core AudioKevin Avila
 
Itp 120 Chapt 19 2009 Binary Input & Output
Itp 120 Chapt 19 2009 Binary Input & OutputItp 120 Chapt 19 2009 Binary Input & Output
Itp 120 Chapt 19 2009 Binary Input & Outputphanleson
 
Introduction to AV Foundation
Introduction to AV FoundationIntroduction to AV Foundation
Introduction to AV FoundationChris 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
 
Understanding Character Encodings
Understanding Character EncodingsUnderstanding Character Encodings
Understanding Character EncodingsMobisoft Infotech
 
Symbian OS - Descriptors
Symbian OS - DescriptorsSymbian OS - Descriptors
Symbian OS - DescriptorsAndreas Jakl
 
Batch uploading to the Internet Archive using Python
Batch uploading to the Internet Archive using PythonBatch uploading to the Internet Archive using Python
Batch uploading to the Internet Archive using PythonAlison Harvey
 
Beginning html5 media, 2nd edition
Beginning html5 media, 2nd editionBeginning html5 media, 2nd edition
Beginning html5 media, 2nd editionser
 
[@NaukriEngineering] Video handlings on apple platforms
[@NaukriEngineering] Video handlings on apple platforms[@NaukriEngineering] Video handlings on apple platforms
[@NaukriEngineering] Video handlings on apple platformsNaukri.com
 
Galaxy presentation.pptx
Galaxy presentation.pptxGalaxy presentation.pptx
Galaxy presentation.pptxtavo957203
 
Joost de Wit (Media Distillery) - Technology Update - Watskeburt?!
Joost de Wit (Media Distillery) - Technology Update - Watskeburt?!Joost de Wit (Media Distillery) - Technology Update - Watskeburt?!
Joost de Wit (Media Distillery) - Technology Update - Watskeburt?!Media Perspectives
 
Software Internationalization Crash Course
Software Internationalization Crash CourseSoftware Internationalization Crash Course
Software Internationalization Crash CourseWill Iverson
 
CHAPTER 5 mechanical engineeringasaaa.pptx
CHAPTER 5 mechanical engineeringasaaa.pptxCHAPTER 5 mechanical engineeringasaaa.pptx
CHAPTER 5 mechanical engineeringasaaa.pptxSadhilAggarwal
 
Welcome to International Journal of Engineering Research and Development (IJERD)
Welcome to International Journal of Engineering Research and Development (IJERD)Welcome to International Journal of Engineering Research and Development (IJERD)
Welcome to International Journal of Engineering Research and Development (IJERD)IJERD Editor
 
TCUK 2013 - Martin Block - Creating narrated videos for user assistance
TCUK 2013 - Martin Block - Creating narrated videos for user assistanceTCUK 2013 - Martin Block - Creating narrated videos for user assistance
TCUK 2013 - Martin Block - Creating narrated videos for user assistanceTCUK Conference
 
06 - ELF format, knowing your friend
06 - ELF format, knowing your friend06 - ELF format, knowing your friend
06 - ELF format, knowing your friendAlexandre Moneger
 
Aplus essentials-exam-cram
Aplus essentials-exam-cramAplus essentials-exam-cram
Aplus essentials-exam-cramPeter Sonko
 
HTML5 vs Silverlight
HTML5 vs SilverlightHTML5 vs Silverlight
HTML5 vs SilverlightMatt Casto
 
HTML5 Multimedia Accessibility
HTML5 Multimedia AccessibilityHTML5 Multimedia Accessibility
HTML5 Multimedia Accessibilitybrucelawson
 

Ähnlich wie AV Foundation Video Tricks (20)

Voice That Matter 2010 - Core Audio
Voice That Matter 2010 - Core AudioVoice That Matter 2010 - Core Audio
Voice That Matter 2010 - Core Audio
 
Itp 120 Chapt 19 2009 Binary Input & Output
Itp 120 Chapt 19 2009 Binary Input & OutputItp 120 Chapt 19 2009 Binary Input & Output
Itp 120 Chapt 19 2009 Binary Input & Output
 
Ig2 task 1 work sheet
Ig2 task 1 work sheetIg2 task 1 work sheet
Ig2 task 1 work sheet
 
Introduction to AV Foundation
Introduction to AV FoundationIntroduction to AV Foundation
Introduction to AV Foundation
 
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)
 
Understanding Character Encodings
Understanding Character EncodingsUnderstanding Character Encodings
Understanding Character Encodings
 
Symbian OS - Descriptors
Symbian OS - DescriptorsSymbian OS - Descriptors
Symbian OS - Descriptors
 
Batch uploading to the Internet Archive using Python
Batch uploading to the Internet Archive using PythonBatch uploading to the Internet Archive using Python
Batch uploading to the Internet Archive using Python
 
Beginning html5 media, 2nd edition
Beginning html5 media, 2nd editionBeginning html5 media, 2nd edition
Beginning html5 media, 2nd edition
 
[@NaukriEngineering] Video handlings on apple platforms
[@NaukriEngineering] Video handlings on apple platforms[@NaukriEngineering] Video handlings on apple platforms
[@NaukriEngineering] Video handlings on apple platforms
 
Galaxy presentation.pptx
Galaxy presentation.pptxGalaxy presentation.pptx
Galaxy presentation.pptx
 
Joost de Wit (Media Distillery) - Technology Update - Watskeburt?!
Joost de Wit (Media Distillery) - Technology Update - Watskeburt?!Joost de Wit (Media Distillery) - Technology Update - Watskeburt?!
Joost de Wit (Media Distillery) - Technology Update - Watskeburt?!
 
Software Internationalization Crash Course
Software Internationalization Crash CourseSoftware Internationalization Crash Course
Software Internationalization Crash Course
 
CHAPTER 5 mechanical engineeringasaaa.pptx
CHAPTER 5 mechanical engineeringasaaa.pptxCHAPTER 5 mechanical engineeringasaaa.pptx
CHAPTER 5 mechanical engineeringasaaa.pptx
 
Welcome to International Journal of Engineering Research and Development (IJERD)
Welcome to International Journal of Engineering Research and Development (IJERD)Welcome to International Journal of Engineering Research and Development (IJERD)
Welcome to International Journal of Engineering Research and Development (IJERD)
 
TCUK 2013 - Martin Block - Creating narrated videos for user assistance
TCUK 2013 - Martin Block - Creating narrated videos for user assistanceTCUK 2013 - Martin Block - Creating narrated videos for user assistance
TCUK 2013 - Martin Block - Creating narrated videos for user assistance
 
06 - ELF format, knowing your friend
06 - ELF format, knowing your friend06 - ELF format, knowing your friend
06 - ELF format, knowing your friend
 
Aplus essentials-exam-cram
Aplus essentials-exam-cramAplus essentials-exam-cram
Aplus essentials-exam-cram
 
HTML5 vs Silverlight
HTML5 vs SilverlightHTML5 vs Silverlight
HTML5 vs Silverlight
 
HTML5 Multimedia Accessibility
HTML5 Multimedia AccessibilityHTML5 Multimedia Accessibility
HTML5 Multimedia Accessibility
 

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
 
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
 
iOS Media APIs (MobiDevDay Detroit, May 2013)
iOS Media APIs (MobiDevDay Detroit, May 2013)iOS Media APIs (MobiDevDay Detroit, May 2013)
iOS Media APIs (MobiDevDay Detroit, May 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 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
 
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 (13)

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)
 
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)
 
iOS Media APIs (MobiDevDay Detroit, May 2013)
iOS Media APIs (MobiDevDay Detroit, May 2013)iOS Media APIs (MobiDevDay Detroit, May 2013)
iOS Media APIs (MobiDevDay Detroit, May 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 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)
 
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

Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfSeasiaInfotech2
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesZilliz
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 

Kürzlich hochgeladen (20)

Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdf
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector Databases
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 

AV Foundation Video Tricks

  • 1. Stupid Video Tricks Chris Adamson • @invalidname CocoaConf DC • March, 2014
  • 2. AV Foundation • Framework for working with time-based media • Audio, video, timed text (captions / subtitles), timecode • iOS 4.0 and up, Mac OS X 10.7 (Lion) and up • Replacing QuickTime on Mac
  • 3. Ordinary AV Foundation stuff • Playback: AVAsset + AVPlayer • Capture to file: AVCaptureSession + AVCaptureDeviceInput + AVCaptureMovieFileOutput • Editing: AVComposition + AVExportSession
  • 4. But Why Be Ordinary? http://www.crunchyroll.com/my-ordinary-life
  • 5. Introductory Trick • AVPlayerLayer and AVCaptureVideoPreviewLayer are subclasses of CALayer • We can do lots of neat things with CALayers
  • 7. Make an AVPlayerLayer self.player = [AVPlayer playerWithPlayerItem: [AVPlayerItem playerItemWithAsset:self.asset]]; self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player]; self.playerLayer.videoGravity = AVLayerVideoGravityResizeAspect; [self.playerView.layer addSublayer:self.playerLayer]; self.playerLayer.frame = self.playerView.bounds;
  • 8. Animate the layer CABasicAnimation *animateRotation; animateRotation = [CABasicAnimation animationWithKeyPath:@"transform"]; CATransform3D layerTransform = self.playerLayer.transform; layerTransform = CATransform3DRotate(layerTransform, M_PI, 1.0, 1.0, 0.0); animateRotation.toValue = [NSValue valueWithCATransform3D:layerTransform]; animateRotation.duration = 2.0; animateRotation.removedOnCompletion = NO; animateRotation.fillMode = kCAFillModeForwards; animateRotation.repeatCount = 1000; animateRotation.cumulative = YES; [self.playerLayer addAnimation:animateRotation forKey:@"transform"];
  • 10. AV Foundation Core Audio Core Media Video Toolbox Core Video
  • 11. AV Foundation Core Audio Core Media Video Toolbox Core Video
  • 12. AV Foundation Core Audio Core Media Video Toolbox Core Video
  • 14. Core Media • Opaque types to represent time: CMTime, CMTimeRange • Opaque types to represent media samples and their contents: CMSampleBuffer, CMBlockBuffer, CMFormatDescription
  • 15. CMSampleBuffer • Provides timing information for one or more samples: when does this play and for how long? • Contains either • CVImageBuffer – visual data (video frames) • CMBlockBuffer — arbitrary data (sound, subtitles, timecodes)
  • 16. Use & Abuse of CMSampleBuffers • AVCaptureDataOutput provides CMSampleBuffers in sample delegate callback • AVAssetReader provides CMSampleBuffers read from disk • AVAssetWriter accepts CMSampleBuffers to write to disk
  • 17. Demo
  • 18. How the Heck Does that Work? • Movies have tracks, tracks have media, media have sample data • All contents of a QuickTime file are defined in the QuickTime File Format documentation
  • 19.
  • 20. Subtitle Sample Data Subtitle sample data consists of a 16-‐bit word that specifies the length (number of bytes) of the subtitle text, followed by the subtitle text and then by optional sample extensions. The subtitle text is Unicode text, encoded either as UTF-‐8 text or UTF-‐16 text beginning with a UTF-‐16 BYTE ORDER MARK ('uFEFF') in big or little endian order. There is no null termination for the text. Following the subtitle text, there may be one or more atoms containing additional information for selecting and drawing the subtitle. Table 4-‐12 (page 203) lists the currently defined subtitle sample extensions. Table 4-12 Subtitle sample extensions DescriptionSubtitle sample extension The presence of this atom indicates that the sample contains a forced subtitle. This extension has no data. Forced subtitles are shown automatically when appropriate without any interaction from the user. If any sample contains a forced subtitle, the Some Samples Are Forced (0x40000000) flag must also be set in the display flags. Consider an example where the primary language of the content is English, but the user has chosen to listen to a French dub of the audio. If a scene in the video displays something in English that is important to the plot or the content (such as a newspaper headline), a forced subtitle displays the content translated into French. In this case, the subtitle is linked (“forced”) to the French language sound track. If this atom is not present, the subtitle is typically simply a translation of the audio content, which a user can choose to display or hide. 'frcd' Style information for the subtitle. This atom allows you to override the default style in the sample description or to define more than one style within a sample. See “Subtitle Style Atom” (page 204). 'styl' Override of the default text box for this sample. Used only if the 0x20000000 display flag is set in the sample description and, in that case, only the top is considered. Even so, all fields should be set as though they are considered. See “Text Box atom” (page 205). 'tbox' Text wrap. Set the one-‐byte payload to 0x00 for no wrapping or 0x01 for automatic soft wrapping. 'twrp' Media Data Atom Types Subtitle Media 2014-‐02-‐11 | Copyright © 2004, 2014 Apple Inc. All Rights Reserved. 203
  • 21. Subtitle Sample Data! Subtitle sample data consists of a 16-bit word that specifies the length (number of bytes) of the subtitle text, followed by the subtitle text and then by optional sample extensions. The subtitle text is Unicode text, encoded either as UTF-8 text or UTF-16 text beginning with a UTF-16 BYTE ORDER MARK ('uFEFF') in big or little endian order. There is no null termination for the text.! Following the subtitle text, there may be one or more atoms containing additional information for selecting and drawing the subtitle.!
  • 22. I Iz In Ur Subtitle Track… AVAssetReaderTrackOutput *subtitleTrackOutput = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:subtitleTracks[0] outputSettings:nil]; ! // ... while (reading) { CMSampleBufferRef sampleBuffer = [subtitleTrackOutput copyNextSampleBuffer]; if (sampleBuffer == NULL) { AVAssetReaderStatus status = subtitleReader.status; if ((status == AVAssetReaderStatusCompleted) || (status == AVAssetReaderStatusFailed) || (status == AVAssetReaderStatusCancelled)) { reading = NO; NSLog (@"ending with reader status %d", status); } } else { CMTime presentationTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer) ; CMTime duration = CMSampleBufferGetDuration(sampleBuffer);
  • 23. …Readin Ur CMBlockBuffers CMBlockBufferRef blockBuffer = CMSampleBufferGetDataBuffer(sampleBuffer); size_t dataSize =CMBlockBufferGetDataLength(blockBuffer); if (dataSize > 0) { UInt8* data = malloc(dataSize); OSStatus cmErr = CMBlockBufferCopyDataBytes (blockBuffer, 0, dataSize, data);
  • 24.
  • 25. Subtitle Summary • AVAssetReaderOutput provides CMSampleBuffers • Get timing info with CMSampleBufferGetPresentationTimestamp() and CMSampleGetDuration() • Get raw data with CMBlockBufferGet…() functions • Have at it
  • 27. AV Foundation Core Audio Core Media Video Toolbox Core Video
  • 31. Potential Uses • Run captured / read-in audio through effects in an AUGraph • See “AVCaptureAudioDataOutput To AudioUnit” examples (iOS & OS X) from WWDC 2012 • May make more sense for audio-oriented apps to do capture / file reads entirely from Core Audio
  • 33. AV Foundation Core Audio Core Media Video Toolbox Core Video
  • 35. • CMSampleBuffers provide CVImageBuffers • Two sub-types: CVPixelBufferRef, CVOpenGLESTextureRef • Pixel buffers allow us to work with bitmaps, via CVPixelBufferGetBaseAddress() • Note: Must wrap calls with CVPixelBufferLockBaseAddress(), CVPixelBufferUnlockBaseAddress() Core Media Core Video
  • 36. Use & Abuse of CVImageBuffers • Can be used to create Core Image CIImages • iOS: -[CIImage imageWithCVPixelBuffer:] • OS X: -[CIImage imageWithCVImageBuffer:] • CIImages can be used to do lots of stuff…
  • 37. Demo
  • 38. Recipe • Create CIContext from EAGLContext • Create CIFilter • During capture callback • Convert pixel buffer to CIImage • Run through filter • Draw to CIContext
  • 39. Set Up GLKView if (! self.glkView.context.API != kEAGLRenderingAPIOpenGLES2) { EAGLContext *eagl2Context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; self.glkView.context = eagl2Context; } self.glContext = self.glkView.context; // we'll do the updating, thanks self.glkView.enableSetNeedsDisplay = NO;
  • 40. Make CIContext // make CIContext from GL context, clearing out default color space self.ciContext = [CIContext contextWithEAGLContext:self.glContext options:@{kCIContextWorkingColorSpace : [NSNull null]} ]; [self.glkView bindDrawable]; // from Core Image Fun House: _glkDrawBounds = CGRectZero; _glkDrawBounds.size.width = self.glkView.drawableWidth; _glkDrawBounds.size.height = self.glkView.drawableHeight; See also iOS Core Image Fun House from WWDC 2013
  • 41. Get RGB in Capture Delegate self.videoDataOutput = [[AVCaptureVideoDataOutput alloc] init]; [self.videoDataOutput setSampleBufferDelegate:self queue:self.videoDataOutputQueue]; [self.captureSession addOutput: self.videoDataOutput]; NSDictionary *videoSettings = @{ (id) kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_32BGRA)}; [self.videoDataOutput setVideoSettings:videoSettings]; Note: 32BGRA and two flavors of 4:2:0 YCbCr are the only valid pixel formats for video capture on iOS
  • 42. Create CIFilter self.pixellateFilter = [CIFilter filterWithName:@"CIPixellate"]; [self.pixellateFilter setValue:[CIVector vectorWithX:100.0 Y:100.0] forKey:@"inputCenter"]; [self setPixellateFilterScale:self.pixellationScaleSlider.value];
  • 43. Set CIFilter Params - (IBAction)handleScaleSliderValueChanged:(UISlider*) sender { [self setPixellateFilterScale:sender.value]; } ! -(void) setPixellateFilterScale: (CGFloat) scale { [self.pixellateFilter setValue:[NSNumber numberWithFloat:scale] forKey:@"inputScale"]; }
  • 44. Callback: Apply Filter CVImageBufferRef cvBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); CVPixelBufferLockBaseAddress(cvBuffer,0); CIImage *bufferCIImage = [CIImage imageWithCVPixelBuffer:cvBuffer]; ! [self.pixellateFilter setValue:bufferCIImage forKey:kCIInputImageKey]; bufferCIImage = [self.pixellateFilter valueForKey:kCIOutputImageKey];
  • 45. Callback: Draw to GLKView [self.glkView bindDrawable]; if (self.glContext != [EAGLContext currentContext]) { [EAGLContext setCurrentContext: self.glContext]; } // drawing code here is from WWDC 2013 iOS Core Image Fun House // clear eagl view to grey glClearColor(0.5, 0.5, 0.5, 1.0); glClear(GL_COLOR_BUFFER_BIT); // set the blend mode to "source over" so that CI will use that glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); CGRect drawRect = bufferCIImage.extent; [self.ciContext drawImage:bufferCIImage inRect:self.glkDrawBounds fromRect:drawRect]; [self.glkView display]; CVPixelBufferUnlockBaseAddress(cvBuffer, 0);
  • 49. There are lots of CIFilters CICategoryBlur ! ! CIBoxBlur ! ! CIDiscBlur ! ! CIGaussianBlur ! ! CIMedianFilter ! ! CIMotionBlur ! ! CINoiseReduction ! ! CIZoomBlur CICategoryColorAdjust ment ! ! CIColorClamp ! ! CIColorControls ! ! CIColorMatrix ! ! CIColorPolynomial ! ! CIExposureAdjust ! ! CIGammaAdjust ! ! CIHueAdjust ! ! CILinearToSRGBToneCurv e ! ! CISRGBToneCurveToLinea r ! ! CITemperatureAndTint ! ! CIToneCurve ! ! CIVibrance ! ! CIWhitePointAdjust CICategoryColorEffect ! ! CIColorCrossPolynomial ! ! CIColorCube ! ! CIColorCubeWithColorSp ace ! ! CIColorInvert ! ! CIColorMap ! ! CIColorMonochrome ! ! CIColorPosterize ! ! CIFalseColor ! ! CIMaskToAlpha ! ! CIMaximumComponent ! ! CIMinimumComponent ! ! CIPhotoEffectChrome ! ! CIPhotoEffectFade ! ! CIPhotoEffectInstant ! ! CIPhotoEffectMono ! ! CIPhotoEffectNoir ! ! CIPhotoEffectProcess ! ! CIPhotoEffectTonal ! ! CIPhotoEffectTransfer ! ! CISepiaTone ! ! CIVignette ! ! CIVignetteEffect CICategoryComposite Operation ! ! CIAdditionCompositing ! ! CIColorBlendMode ! ! CIColorBurnBlendMode ! ! CIColorDodgeBlendMode ! ! CIDarkenBlendMode ! ! CIDifferenceBlendMode ! ! CIExclusionBlendMode ! ! CIHardLightBlendMode ! ! CIHueBlendMode ! ! CILightenBlendMode ! ! CILuminosityBlendMode ! ! CIMaximumCompositing ! ! CIMinimumCompositing ! ! CIMultiplyBlendMode ! ! CIMultiplyCompositing ! ! CIOverlayBlendMode ! ! CISaturationBlendMode ! ! CIScreenBlendMode ! ! CISoftLightBlendMode ! ! CISourceAtopCompositin g ! ! CISourceInCompositing ! ! CISourceOutCompositing ! ! CISourceOverCompositin g CICategoryDistortionE ffect ! ! CIBumpDistortion ! ! CIBumpDistortionLinear ! ! CICircleSplashDistorti on ! ! CICircularWrap ! ! CIDroste ! ! CIDisplacementDistorti on ! ! CIGlassDistortion ! ! CIGlassLozenge ! ! CIHoleDistortion ! ! CILightTunnel ! ! CIPinchDistortion ! ! CIStretchCrop ! ! CITorusLensDistortion ! ! CITwirlDistortion ! ! CIVortexDistortion CICategoryGenerator ! CICheckerboardGenerator ! ! CIConstantColorGenerat or ! ! CILenticularHaloGenera tor ! ! CIQRCodeGenerator ! ! CIRandomGenerator ! ! CIStarShineGenerator ! ! CIStripesGenerator ! ! CISunbeamsGenerator CICategoryGeometryA djustment ! ! CIAffineTransform ! ! CICrop ! ! CILanczosScaleTransfor m ! ! CIPerspectiveTransform ! ! CIPerspectiveTransform WithExtent ! ! CIStraightenFilter CICategoryGradient ! ! CIGaussianGradient ! ! CILinearGradient ! ! CIRadialGradient ! ! CISmoothLinearGradient CICategoryHalftoneEff ect
  • 50. Demo
  • 51. CIColorCube Maps colors from one RGB “cube” to another http://en.wikipedia.org/wiki/RGB_color_space
  • 52. Using CIColorCube CIColorCube maps green(-ish) colors to 0.0 alpha, all other colors pass through
  • 54. CIColorCube Data const unsigned int size = 64; size_t cubeDataSize = size * size * size * sizeof (float) * 4; float *keyCubeData = (float *)malloc (cubeDataSize); float rgb[3], hsv[3], *keyC = keyCubeData; // Populate cube with a simple gradient going from 0 to 1 for (int z = 0; z < size; z++){ rgb[2] = ((double)z)/(size-1); // Blue value for (int y = 0; y < size; y++){ rgb[1] = ((double)y)/(size-1); // Green value for (int x = 0; x < size; x ++){ rgb[0] = ((double)x)/(size-1); // Red value ! // Convert RGB to HSV // You can find publicly available rgbToHSV functions on the Internet ! RGBtoHSV(rgb[0], rgb[1], rgb[2], &hsv[0], &hsv[1], &hsv[2]); ! // RGBtoHSV uses 0 to 360 for hue, while UIColor (used above) uses 0 to 1. hsv[0] /= 360.0; // Use the hue value to determine which to make transparent // The minimum and maximum hue angle depends on // the color you want to remove bool keyed = (hsv[0] > minHueAngle && hsv[0] < maxHueAngle) && (hsv[1] > minSaturation && hsv[1] < maxSaturation) && (hsv[2] > minBrightness && hsv[2] < maxBrightness); float alpha = keyed ? 0.0f : 1.0f; // re-calculate c pointer keyC = (((z * size * size) + (y * size) + x) * sizeof(float)) + keyCubeData; // Calculate premultiplied alpha values for the cube keyC[0] = rgb[0] * alpha; keyC[1] = rgb[1] * alpha; keyC[2] = rgb[2] * alpha; keyC[3] = alpha; } } } See “Chroma Key Filter Recipe” in Core Image Programming Guide
  • 55. Create CIColorCube from mapping data // Create memory with the cube data NSData *data = [NSData dataWithBytesNoCopy:keyCubeData length:cubeDataSize freeWhenDone:YES]; self.colorCubeFilter = [CIFilter filterWithName:@"CIColorCube"]; [self.colorCubeFilter setValue:[NSNumber numberWithInt:size] forKey:@"inputCubeDimension"]; // Set data for cube [self.colorCubeFilter setValue:data forKey:@"inputCubeData"];
  • 56. Create CISourceOverCompositing // source over filter self.sourceOverFilter = [CIFilter filterWithName: @"CISourceOverCompositing"]; CIImage *backgroundCIImage = [CIImage imageWithCGImage: self.backgroundImage.CGImage]; [self.sourceOverFilter setValue:backgroundCIImage forKeyPath:@"inputBackgroundImage"];
  • 57. Apply Filters in Delegate Callback CIImage *bufferCIImage = [CIImage imageWithCVPixelBuffer: cvBuffer]; [self.colorCubeFilter setValue:bufferCIImage forKey:kCIInputImageKey]; CIImage *keyedCameraImage = [self.colorCubeFilter valueForKey: kCIOutputImageKey]; [self.sourceOverFilter setValue:keyedCameraImage forKeyPath:kCIInputImageKey]; CIImage *compositedImage = [self.sourceOverFilter valueForKeyPath: kCIOutputImageKey]; Then draw compositedImage to CIContext as before
  • 58. More Fun with Filters • Alpha Matte: Use CIColorCube to map green to white (or transparent), everything else to black • Can then use this with other filters to do edge work on the “foreground” object • Be sure that any filters you use are of category CICategoryVideo.
  • 59. More Fun With CIContexts • Can write effected pixels to a movie file with AVAssetWriterOutput • Use base address of CIContext to create a new CVPixelBuffer, use this and timing information to create a CMSampleBuffer • AVAssetWriterInputPixelBufferAdaptor makes this slightly easier
  • 60. Recap • Most good tricks start with CMSampleBuffers • Audio: convert to Core Audio types • Video: convert to CIImage • Other: get CMBlockBuffer and parse by hand
  • 62. Q&A Slides at http://www.slideshare.net/invalidname/ See comments there for link to source code ! invalidname [at] gmail.com @invalidname (Twitter, app.net) http://www.subfurther.com/blog