视频不能在设备上播放但是玩ov模拟器

时间:2015-02-02 08:21:16

标签: ios xcode mpmovieplayercontroller avmutablecomposition

我真的坚持这个,我合并了视频(mp4类保存在xcode中,mov-来自用户照片库)和音频(mp3类保存在xcode中)。在模拟器上它工作正常并显示视频和音频,但在设备上它不显示视频只播放声音。这里是合并的代码:`AVMutableComposition * mixComposition = [AVMutableComposition composition];

//Audio
//Now first load your audio file using AVURLAsset. Make sure you give the correct path of your videos.
NSURL *audio_url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:_video.musicFileName ofType:@"mp3"]];
AVURLAsset  *audioAsset = [[AVURLAsset alloc] initWithURL:audio_url options:nil];
CMTimeRange audio_timeRange = CMTimeRangeMake(kCMTimeZero, audioAsset.duration);

//Now we are creating the first AVMutableCompositionTrack containing our audio and add it to our AVMutableComposition object.
AVMutableCompositionTrack *compositionAudioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
[compositionAudioTrack insertTimeRange:audio_timeRange ofTrack:[[audioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] atTime:kCMTimeZero error:nil];


//Video
AVMutableCompositionTrack *compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
NSString *fistPartMovieFilename = @"firstpart";
NSString *lastPartMovieFilename = @"lastpart";

//[_video.selectedVideosFileName insertObject:fistPartMovieFilename atIndex:0];
//[_video.selectedVideosFileName addObject:lastPartMovieFilename];
NSMutableArray *timeRanges = [NSMutableArray arrayWithCapacity:_video.selectedVideosFileName.count];
NSMutableArray *tracks = [NSMutableArray arrayWithCapacity:_video.selectedVideosFileName.count];

NSLog(@"_video.selectedVideosFileName %@",_video.selectedVideosFileName);
for (int i=0; i<[_video.selectedVideosFileName count]; i++)
{
    AVURLAsset *assetClip;
    NSString *fileName = [_video.selectedVideosFileName objectAtIndex:i];

    if ([[_video.selectedVideosFileName objectAtIndex:i] isKindOfClass:[NSURL class]])
    {
        assetClip = [AVAsset assetWithURL:[_video.selectedVideosFileName objectAtIndex:i]];
    }
    else
    {
        assetClip = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:[NSString stringWithString:fileName] ofType:@"mp4"]] options:nil];

    }

    AVAssetTrack *clipVideoTrack = [[assetClip tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
    [timeRanges addObject:[NSValue valueWithCMTimeRange:CMTimeRangeMake(kCMTimeZero, assetClip.duration)]];
    [tracks addObject:clipVideoTrack];

    NSLog(@"timeRanges %@",timeRanges);
    NSLog(@"tracks %@",tracks);
    NSLog(@"assetClip %@",assetClip);
    NSLog(@"clipVideoTrack %@",clipVideoTrack);


}

NSError *error = nil;
BOOL sucsess = [compositionVideoTrack insertTimeRanges:timeRanges
                                              ofTracks:tracks
                                                atTime:kCMTimeZero
                                                 error:&error];

if (!sucsess || error) {
    NSLog(@"video error %@", error);


}

尝试设备时遇到的错误是:视频错误  错误域= AVFoundationErrorDomain代码= -11800“操作无法完成”UserInfo = 0x1704707c0 {NSUnderlyingError = 0x174247050“操作无法完成。(OSStatus error -12780。)”,NSLocalizedFailureReason =发生未知错误(-12780),NSLocalizedDescription =操作无法完成

 NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *docsDir = [dirPaths objectAtIndex:0];
    NSString *outputFilePath =  [docsDir stringByAppendingPathComponent:[NSString stringWithFormat:@"Zagoori-%d.mov",arc4random() % 1000]];
    NSURL *outputFileUrl = [NSURL fileURLWithPath:outputFilePath];

    if ([[NSFileManager defaultManager] fileExistsAtPath:outputFilePath])
        [[NSFileManager defaultManager] removeItemAtPath:outputFilePath error:nil];

    //Now create an AVAssetExportSession object that will save your final video at specified path.
    AVAssetExportSession *_assetExport = [[AVAssetExportSession alloc] initWithAsset:mixComposition
                                                                          presetName:AVAssetExportPresetLowQuality];

    NSLog(@"supportedFileTypes %@", [_assetExport supportedFileTypes]);
    _assetExport.outputFileType = @"com.apple.quicktime-movie";
    _assetExport.outputURL = outputFileUrl;
    [_assetExport exportAsynchronouslyWithCompletionHandler:^
     {
         dispatch_async(dispatch_get_main_queue(), ^{

             switch ([_assetExport status]) {
                 case AVAssetExportSessionStatusExporting:
                     NSLog(@"Export in progress ");
                 case AVAssetExportSessionStatusFailed:
                     NSLog(@"Export failed (%ld): %@", (long)[[_assetExport error] code], [[_assetExport error] localizedFailureReason]);
                     [_assetExport cancelExport];
                     break;
                 case AVAssetExportSessionStatusCancelled:
                     NSLog(@"Export canceled");
                     break;
                 case AVAssetExportSessionStatusCompleted:
                     NSLog(@"Export done");
                     [self exportDidFinish:_assetExport];

                   //  NSLog (@"finished writing %f", [dtStartDate timeIntervalSinceNow]);
                     break;
                 case AVAssetExportSessionStatusWaiting:
                     NSLog (@"AVAssetExportSessionStatusWaiting");
                     break;
                 case AVAssetExportSessionStatusUnknown:
                     NSLog (@"AVAssetExportSessionStatusUnknown");
                     break;
             }

         });


     }]; 

-(void)loadMoviePlayer:(NSURL*)moviePath {
    _moviePlayerController = [[MPMoviePlayerController alloc]
                   initWithContentURL:moviePath];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                                  selector:@selector(introMovieFinished:)
                                                      name:MPMoviePlayerPlaybackDidFinishNotification
                                                    object:_moviePlayerController];

    _moviePlayerController.view.hidden = NO;
    _moviePlayerController.view.frame = CGRectMake(0, 0, _videoView.frame.size.width,
                                        _videoView.frame.size.height);
    _moviePlayerController.view.backgroundColor = [UIColor clearColor];
    _moviePlayerController.scalingMode = MPMovieScalingModeAspectFit;
    _moviePlayerController.fullscreen = NO;
    [_moviePlayerController prepareToPlay];
    [_moviePlayerController readyForDisplay];
    [_moviePlayerController setControlStyle:MPMovieControlStyleDefault];
    _moviePlayerController.shouldAutoplay = YES;
    [_videoView addSubview:_moviePlayerController.view];
    [_videoView setHidden:NO];
}

我真的对问题无能为力,请帮助! :)

1 个答案:

答案 0 :(得分:0)

所以我发现了问题,它是由AVURLAsset实例引起的

由于AVURLAsset * assetClip位于for循环内部,因此它在其外部无效,也不是我提取的轨道。

我将assetClip保存在一个数组中,解决了这个问题。