Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Building a Playlist with AV Foundation

Building a Playlist with AV Foundation

Slides from my talk at iOSDevCampDC 2013 about building playlists with AV Foundation.

Josh Johnson

August 24, 2013
Tweet

More Decks by Josh Johnson

Other Decks in Programming

Transcript

  1. Building a Playlist with AV Foundation Josh Johnson @jnjosh |

    αjnjosh | jnjosh.com
  2. or: A crash course to AV Foundation  with music.

    Josh Johnson @jnjosh | αjnjosh | jnjosh.com
  3. Why just music? AV Foundation Audio-only Classes

  4. None
  5. None
  6. UIKit Core Audio Core Media Core Animation Media Player AV

    Foundation
  7. MPMusicPlayerController

  8. MPMusicPlayerController *player =  [MPMusicPlayerController applicationMusicPlayer]; ! // Access the

    music through the iPod Library Access API MPMediaQuery *query = [MPMediaQuery artistsQuery]; ! [query addFilterPredicate:[MPMediaPropertyPredicate predicateWithValue:@"David Hasselhoff" forProperty:MPMediaItemPropertyArtist comparisonType:MPMediaPredicateComparisonEqualTo]]; [query setGroupingType:MPMediaGroupingArtist]; ! // Let the player have the query [player setQueueWithQuery:query]; ! // Listen to the musical stylings of David Hasselhoff [player play];
  9. None
  10. UIKit Core Audio Core Media Core Animation Media Player AV

    Foundation
  11. Players

  12. AVPlayer AVQueuePlayer

  13. AVURLAsset *asset =  [AVURLAsset URLAssetWithURL:<# hasselhoff.mp3 #> options:nil]; !

    ! AVPlayerItem *playerItem =  [[AVPlayerItem alloc] initWithAsset:asset]; ! ! AVPlayer *audioPlayer =  [[AVPlayer alloc] initWithPlayerItem:playerItem]; ! ! [audioPlayer play];
  14. AVURLAsset *asset =  [AVURLAsset URLAssetWithURL:<# hasselhoff.mp3 #> options:nil]; !

    AVPlayerItem *item1 =  [[AVPlayerItem alloc] initWithAsset:asset]; ! // setup asset2 and item2 ! AVQueuePlayer *audioPlayer =  [AVQueuePlayer queuePlayerWithItems:@[ item1, item2 ]]; ! ! [audioPlayer play];
  15. Assets

  16. AVURLAsset *asset =  [AVURLAsset URLAssetWithURL:song.url options:nil]; ! ! [asset

    loadValuesAsynchronouslyForKeys:@[ @"tracks" ] completionHandler:^{  ! NSArray *assetTracks = [asset tracksWithMediaType:AVMediaTypeAudio]; // ... ! }];
  17. Time

  18. CMTime fiveSeconds = CMTimeMake(5, 1); CMTime halfSecond = CMTimeMake(1, 2);

    CMTime thirtyFPS = CMTimeMake(1, 30); CMTimeAdd(<#CMTime addend1#>, <#CMTime addend2#>) ! CMTimeSubtract(<#CMTime minuend#>, <#CMTime subtrahend#>) ! CMTimeShow(<#CMTime time#>)
  19. CMTimeRange range = CMTimeRangeMake(CMTimeMake(5, 1), CMTimeMake(5, 1)); ! CMTimeRangeMake(<#CMTime start#>,

    <#CMTime duration#>) ! CMTimeRangeContainsTime(<#CMTimeRange range#>, <#CMTime time#>) ! CMTimeRangeShow(<#CMTimeRange range#>)
  20. Demo

  21. None
  22. Compositions and AudioMix

  23. AVComposition

  24. AVCompositionTrack

  25. AVCompositionTrack AVCompositionTrack

  26. AVCompositionTrack (Video) AVCompositionTrack (Audio)

  27. AVCompositionTrackSegment seconds 50-60 of “the_hoff.mp3” AVCompositionTrackSegment seconds 0-10 of “the_hoff.mp3”

  28. AVURLAsset *asset =  [AVURLAsset URLAssetWithURL:song.url options:nil]; ! ! [asset

    loadValuesAsynchronouslyForKeys:@[ @"tracks" ] completionHandler:^{  ! NSArray *assetTracks = [asset tracksWithMediaType:AVMediaTypeAudio]; // ... ! }];
  29. AVMutableComposition *composition = [AVMutableComposition composition]; AVMutableCompositionTrack *track = [composition addMutableTrackWithMediaType:AVMediaTypeAudio

    preferredTrackID:kCMPersistentTrackID_Invalid]; AVAssetTrack *audioTrack = [assetTracks lastObject]; [track insertTimeRange:audioTrack.timeRange ofTrack:audioTrack atTime:<# CMTime #> error:&error];
  30. A composition is an asset.

  31. AVComposition *compositionAsset = [composition copy]; ! ! AVPlayerItem *playerItem =

    [[AVPlayerItem alloc] initWithAsset:compositionAsset]; ! ! AVPlayer *audioPlayer = [[AVPlayer alloc] initWithPlayerItem:playerItem]; ! ! // Observe `status` for AVPlayerStatusReadyToPlay ! ! [audioPlayer play];
  32. AVMutableAudioMixInputParameters *params =  [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:track]; ! CMTime crossfadeDuration =

    ...; CMTimeRange crossfadeEndRange = CMTimeRangeMake(CMTimeSubtract(CMTimeRangeGetEnd(songRange), crossfadeDuration), crossfadeDuration); ! // set the ramp [params setVolumeRampFromStartVolume:1.0 toEndVolume:0.0 timeRange:crossfadeEndRange]; [audioMixParameters addObject:params]; ! AVMutableAudioMix *audioMix = [AVMutableAudioMix audioMix]; [audioMix setInputParameters:audioMixParameters]; [playerItem setAudioMix:fadeMix];
  33. Demo

  34. None
  35. Questions? You can even ask why so much Hasselhoff?

  36. Thank you! Josh Johnson @jnjosh | αjnjosh | jnjosh.com