2

我正在尝试构建一个应用程序,该应用程序将使用 AVFoundation 类更改视频的组成,但希望能够先播放视频。我已经编写了一些代码来做到这一点,但是当我播放视频时声音不起作用。
我尝试使用 Apple 示例代码来执行此操作。
下面是我的代码:

  -(void)loadAssets
 {
NSArray *requestedKeys = [NSArray arrayWithObjects:kTracksKey, kPlayableKey, nil];
/* Tells the asset to load the values of any of the specified keys that are not already loaded. */
[asset loadValuesAsynchronouslyForKeys:requestedKeys completionHandler:
 ^{      
     dispatch_async( dispatch_get_main_queue(), 
                    ^{
                        /* IMPORTANT: Must dispatch to main queue in order to operate on the AVPlayer and AVPlayerItem. */
                        [self prepareToPlayAsset:asset withKeys:requestedKeys];
                    });
 }];
}

- (void)prepareToPlayAsset:(AVURLAsset *)assetURL withKeys:(NSArray *)requestedKeys
{
/* Make sure that the value of each key has loaded successfully. */
for (NSString *thisKey in requestedKeys)
{
    NSError *error = nil;
    AVKeyValueStatus keyStatus = [assetURL statusOfValueForKey:thisKey error:&error];
    if (keyStatus == AVKeyValueStatusFailed)
    {
        [self assetFailedToPrepareForPlayback:error];
        return;
    }
}

/* Use the AVAsset playable property to detect whether the asset can be played. */
if (!assetURL.playable) 
{
    /* Generate an error describing the failure. */
    NSString *localizedDescription = NSLocalizedString(@"Item cannot be played", @"Item cannot be played description");
    NSString *localizedFailureReason = NSLocalizedString(@"The assets tracks were loaded, but could not be made playable.", @"Item cannot be played failure reason");
    NSDictionary *errorDict = [NSDictionary dictionaryWithObjectsAndKeys:
                               localizedDescription, NSLocalizedDescriptionKey, 
                               localizedFailureReason, NSLocalizedFailureReasonErrorKey, 
                               nil];
    NSError *assetCannotBePlayedError = [NSError errorWithDomain:@"StitchedStreamPlayer" code:0 userInfo:errorDict];

    /* Display the error to the user. */
    [self assetFailedToPrepareForPlayback:assetCannotBePlayedError];

    return;
}

/* At this point we're ready to set up for playback of the asset. */

/* Stop observing our prior AVPlayerItem, if we have one. */
if (self.playerItem)
{
    /* Remove existing player item key value observers and notifications. */

    [self.playerItem removeObserver:self forKeyPath:kStatusKey];            

    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:AVPlayerItemDidPlayToEndTimeNotification
                                                  object:self.playerItem];
}

/* Create a new instance of AVPlayerItem from the now successfully loaded AVAsset. */
self.playerItem = [AVPlayerItem playerItemWithAsset:asset];

/* Observe the player item "status" key to determine when it is ready to play. */
[self.playerItem addObserver:self 
                   forKeyPath:kStatusKey 
                      options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
                      context:VideoPlaybackViewControllerStatusObservationContext];

/* When the player item has played to its end time we'll toggle
 the movie controller Pause button to be the Play button */
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(playerItemDidReachEnd:)
                                             name:AVPlayerItemDidPlayToEndTimeNotification
                                           object:self.playerItem];

seekToZeroBeforePlay = NO;

/* Create new player, if we don't already have one. */
if (![self player])
{
    /* Get a new AVPlayer initialized to play the specified player item. */
    self.player=[AVPlayer playerWithPlayerItem:self.playerItem];    
    [self.playerView setPlayer:self.player];


    // Observe the AVPlayer "currentItem" property to find out when any 
     //AVPlayer replaceCurrentItemWithPlayerItem: replacement will/did 
     //occur.
    [self.player addObserver:self 
                  forKeyPath:kCurrentItemKey 
                     options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
                     context:VideoPlaybackViewControllerCurrentItemObservationContext];

}

// Make our new AVPlayerItem the AVPlayer's current item. 
if (self.player.currentItem != self.playerItem)
{
    // Replace the player item with a new player item. The item replacement occurs 
     //asynchronously; observe the currentItem property to find out when the 
     //replacement will/did occur
    [[self player] replaceCurrentItemWithPlayerItem:self.playerItem];

    [self syncUI];
}


 }



 - (void)observeValueForKeyPath:(NSString*) path 
                  ofObject:(id)object 
                    change:(NSDictionary*)change 
                   context:(void*)context
  {
/* AVPlayerItem "status" property value observer. */
if (context == VideoPlaybackViewControllerStatusObservationContext)
{
    [self syncUI];

    AVPlayerStatus status = [[change objectForKey:NSKeyValueChangeNewKey] integerValue];
    switch (status)
    {
            /* Indicates that the status of the player is not yet known because 
             it has not tried to load new media resources for playback */
        case AVPlayerStatusUnknown:
        {
           [self disablePlayerButtons];

        }
            break;

        case AVPlayerStatusReadyToPlay:
        {
            /* Once the AVPlayerItem becomes ready to play, i.e. 
             [playerItem status] == AVPlayerItemStatusReadyToPlay,
             its duration can be fetched from the item. */

            //[self initScrubberTimer];

            //[self enableScrubber];
            [self enablePlayerButtons];

        }
            break;

        case AVPlayerStatusFailed:
        {
            AVPlayerItem *playerItem = (AVPlayerItem *)object;
            [self assetFailedToPrepareForPlayback:playerItem.error];
        }
            break;
    }
}
/* AVPlayer "currentItem" property observer. 
 Called when the AVPlayer replaceCurrentItemWithPlayerItem: 
 replacement will/did occur. */
else if (context == VideoPlaybackViewControllerCurrentItemObservationContext)
{
    AVPlayerItem *newPlayerItem = [change objectForKey:NSKeyValueChangeNewKey];

    /* Is the new player item null? */
    if (newPlayerItem == (id)[NSNull null])
    {
        [self disablePlayerButtons];
        //[self disableScrubber];
    }
    else /* Replacement of player currentItem has occurred */
    {
        /* Set the AVPlayer for which the player layer displays visual output. */
        [self.playerView setPlayer:self.player];

        //[self setViewDisplayName];

        /* Specifies that the player should preserve the video’s aspect ratio and 
         fit the video within the layer’s bounds. */
        //[mPlaybackView setVideoFillMode:AVLayerVideoGravityResizeAspect];

        [self syncUI];
    }
}
else
{
    [super observeValueForKeyPath:path ofObject:object change:change context:context];
}


   }

有什么帮助吗?

4

0 回答 0