MOV到Mp4视频转换iPhone编程



我正在为iPhone的playstation3开发媒体服务器。

我知道PS3不支持。mov文件,所以我必须将其转换为Mp4或PS3支持的其他转码文件。

这就是我所做的,但是如果我设置的文件类型与源文件不同,它就会崩溃。

AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:videoURL options:nil];
NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:avAsset];
if ([compatiblePresets containsObject:AVAssetExportPresetLowQuality])
{
    AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]initWithAsset:avAsset presetName:AVAssetExportPresetLowQuality];
    exportSession.outputURL = [NSURL fileURLWithPath:videoPath];
    exportSession.outputFileType = AVFileTypeMPEG4;
    CMTime start = CMTimeMakeWithSeconds(1.0, 600);
    CMTime duration = CMTimeMakeWithSeconds(3.0, 600);
    CMTimeRange range = CMTimeRangeMake(start, duration);
    exportSession.timeRange = range;
    [exportSession exportAsynchronouslyWithCompletionHandler:^{
        switch ([exportSession status]) {
            case AVAssetExportSessionStatusFailed:
                NSLog(@"Export failed: %@", [[exportSession error] localizedDescription]);
                break;
            case AVAssetExportSessionStatusCancelled:
                NSLog(@"Export canceled");
                break;
            default:
                break;
        }
        [exportSession release];
    }];
}

如果我在这里设置AVFileTypeMPEG4,那么它会崩溃,说"无效的文件类型"。所以我必须将其设置为AVFileTypeQuickTimeMovie它会给出MOV文件

是否可以在iOS中通过AVAssetExportSession将视频从MOV转换为Mp4…或者没有任何第三方库?

presetName使用"AVAssetExportPresetPassthrough"代替"AVAssetExportPresetLowQuality"

 AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]initWithAsset:avAsset presetName:AVAssetExportPresetPassthrough];

MOV与MP4非常相似,你可以改变扩展名并让它工作,Windows Phone不能播放。movs,但可以播放MP4,我所做的就是把扩展名从。MOV改为。MP4,它工作得很好,这是从iphone上拍摄的视频…如果有的话,你可以尝试用AVAssetExporter导出并尝试其中有一种文件类型为MP4和M4A从这里的文件格式uti中可以看到

希望有所帮助

您可以使用AVAssets转换mp4视频

AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:videoURL options:nil];
NSArray *compatiblePresets = [AVAssetExportSession     
exportPresetsCompatibleWithAsset:avAsset];
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]initWithAsset:avAsset presetName:AVAssetExportPresetLowQuality];
NSString* documentsDirectory=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
  exportSession.outputURL = url;
 //set the output file format if you want to make it in other file format (ex .3gp)
 exportSession.outputFileType = AVFileTypeMPEG4;
 exportSession.shouldOptimizeForNetworkUse = YES;
 [exportSession exportAsynchronouslyWithCompletionHandler:^{
 switch ([exportSession status])
 {
      case AVAssetExportSessionStatusFailed:
           NSLog(@"Export session failed");
           break;
      case AVAssetExportSessionStatusCancelled:
           NSLog(@"Export canceled");
           break;
      case AVAssetExportSessionStatusCompleted:
      {
           //Video conversion finished
           NSLog(@"Successful!");
      }
           break;
      default:
           break;
  }
 }];

使用此链接轻松转换视频到mp4。

您还可以找到将视频转换为mp4的示例项目。

您需要AVMutableComposition来完成此操作。因为Asset不能在ios5.0下直接转码到MP4。

- (BOOL)encodeVideo:(NSURL *)videoURL
{
    AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:videoURL options:nil];
    // Create the composition and tracks
    AVMutableComposition *composition = [AVMutableComposition composition];
    AVMutableCompositionTrack *videoTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
    AVMutableCompositionTrack *audioTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
    NSArray *assetVideoTracks = [asset tracksWithMediaType:AVMediaTypeVideo];
    if (assetVideoTracks.count <= 0)
    {
            NSLog(@"Error reading the transformed video track");
            return NO;
    }
    // Insert the tracks in the composition's tracks
    AVAssetTrack *assetVideoTrack = [assetVideoTracks firstObject];
    [videoTrack insertTimeRange:assetVideoTrack.timeRange ofTrack:assetVideoTrack atTime:CMTimeMake(0, 1) error:nil];
    [videoTrack setPreferredTransform:assetVideoTrack.preferredTransform];
    AVAssetTrack *assetAudioTrack = [[asset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
    [audioTrack insertTimeRange:assetAudioTrack.timeRange ofTrack:assetAudioTrack atTime:CMTimeMake(0, 1) error:nil];
    // Export to mp4
    NSString *mp4Quality = [MGPublic isIOSAbove:@"6.0"] ? AVAssetExportPresetMediumQuality : AVAssetExportPresetPassthrough;
    NSString *exportPath = [NSString stringWithFormat:@"%@/%@.mp4",
                                     [NSHomeDirectory() stringByAppendingString:@"/tmp"],
                                     [BSCommon uuidString]];
    NSURL *exportUrl = [NSURL fileURLWithPath:exportPath];
    AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:composition presetName:mp4Quality];
    exportSession.outputURL = exportUrl;
    CMTime start = CMTimeMakeWithSeconds(0.0, 0);
    CMTimeRange range = CMTimeRangeMake(start, [asset duration]);
    exportSession.timeRange = range;
    exportSession.outputFileType = AVFileTypeMPEG4;
    [exportSession exportAsynchronouslyWithCompletionHandler:^{
            switch ([exportSession status])
            {
                case AVAssetExportSessionStatusCompleted:
                       NSLog(@"MP4 Successful!");
                       break;
                case AVAssetExportSessionStatusFailed:
                       NSLog(@"Export failed: %@", [[exportSession error] localizedDescription]);
                       break;
                case AVAssetExportSessionStatusCancelled:
                       NSLog(@"Export canceled");
                       break;
                default:
                       break;
            }
    }];
    return YES;
}

使用以下代码

    NSURL * mediaURL = [info objectForKey:UIImagePickerControllerMediaURL];
    AVAsset *video = [AVAsset assetWithURL:mediaURL];
    AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:video presetName:AVAssetExportPresetMediumQuality];
    exportSession.shouldOptimizeForNetworkUse = YES;
    exportSession.outputFileType = AVFileTypeMPEG4;
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
    basePath = [basePath stringByAppendingPathComponent:@"videos"];
    if (![[NSFileManager defaultManager] fileExistsAtPath:basePath])
        [[NSFileManager defaultManager] createDirectoryAtPath:basePath withIntermediateDirectories:YES attributes:nil error:nil];
    compressedVideoUrl=nil;
    compressedVideoUrl = [NSURL fileURLWithPath:basePath];
    long CurrentTime = [[NSDate date] timeIntervalSince1970];
    NSString *strImageName = [NSString stringWithFormat:@"%ld",CurrentTime];
    compressedVideoUrl=[compressedVideoUrl URLByAppendingPathComponent:[NSString stringWithFormat:@"%@.mp4",strImageName]];
    exportSession.outputURL = compressedVideoUrl;
    [exportSession exportAsynchronouslyWithCompletionHandler:^{
        NSLog(@"done processing video!");
        NSLog(@"%@",compressedVideoUrl);
        if(!dataMovie)
            dataMovie = [[NSMutableData alloc] init];
        dataMovie = [NSData dataWithContentsOfURL:compressedVideoUrl];
    }];

代码

    func encodeVideo(videoURL: NSURL)  {
    let avAsset = AVURLAsset(URL: videoURL, options: nil)
    var startDate = NSDate()
    //Create Export session
    exportSession = AVAssetExportSession(asset: avAsset, presetName: AVAssetExportPresetPassthrough)
    // exportSession = AVAssetExportSession(asset: composition, presetName: mp4Quality)
    //Creating temp path to save the converted video

    let documentsDirectory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0]
    let myDocumentPath = NSURL(fileURLWithPath: documentsDirectory).URLByAppendingPathComponent("temp.mp4").absoluteString
    let url = NSURL(fileURLWithPath: myDocumentPath)
    let documentsDirectory2 = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0] as NSURL
    let filePath = documentsDirectory2.URLByAppendingPathComponent("rendered-Video.mp4")
    deleteFile(filePath)
    //Check if the file already exists then remove the previous file
    if NSFileManager.defaultManager().fileExistsAtPath(myDocumentPath) {
        do {
            try NSFileManager.defaultManager().removeItemAtPath(myDocumentPath)
        }
        catch let error {
            print(error)
        }
    }
     url
    exportSession!.outputURL = filePath
    exportSession!.outputFileType = AVFileTypeMPEG4
    exportSession!.shouldOptimizeForNetworkUse = true
    var start = CMTimeMakeWithSeconds(0.0, 0)
    var range = CMTimeRangeMake(start, avAsset.duration)
    exportSession.timeRange = range
    exportSession!.exportAsynchronouslyWithCompletionHandler({() -> Void in
        switch self.exportSession!.status {
        case .Failed:
            print("%@",self.exportSession?.error)
        case .Cancelled:
            print("Export canceled")
        case .Completed:
            //Video conversion finished
            var endDate = NSDate()
            var time = endDate.timeIntervalSinceDate(startDate)
            print(time)
            print("Successful!")
            print(self.exportSession.outputURL)
        default:
            break
        }
    })

}
func deleteFile(filePath:NSURL) {
    guard NSFileManager.defaultManager().fileExistsAtPath(filePath.path!) else {
        return
    }
    do {
        try NSFileManager.defaultManager().removeItemAtPath(filePath.path!)
    }catch{
        fatalError("Unable to delete file: (error) : (__FUNCTION__).")
    }
}

只是想说URL不能像

[NSURL URLWithString: [@"~/Documents/movie.mov" stringByExpandingTildeInPath]]

必须是

[NSURL fileURLWithPath: [@"~/Documents/movie.mov" stringByExpandingTildeInPath]]

我花了一点时间才弄明白:-)

最新更新