ios 以编程方式将 MOV 到 Mp4 视频转换 iPhone

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8474517/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 15:50:50  来源:igfitidea点击:

MOV to Mp4 video conversion iPhone programmatically

iphoneiosvideo-processing

提问by Elegant Microweb

I am developing media server for Play station 3 in iPhone.

我正在为 iPhone 中的 Play station 3 开发媒体服务器。

I came to know that PS3 doesn't support .MOV file so I have to convert it into Mp4 or something other transcode which PS3 support.

我开始知道 PS3 不支持 .MOV 文件,因此我必须将其转换为 Mp4 或 PS3 支持的其他转码文件。

This is what I have done but it crashes if I set different file type than its source files.

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

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];
    }];
}

If I set AVFileTypeMPEG4 here then it crashes, saying "Invalid file type". So I have to set it to AVFileTypeQuickTimeMovie and it gives MOV file.

如果我在这里设置 AVFileTypeMPEG4 那么它会崩溃,说“无效的文件类型”。所以我必须将它设置为 AVFileTypeQuickTimeMovie 并提供 MOV 文件。

Is it possible in iOS to convert video from MOV to Mp4 through AVAssetExportSession...OR without any Thirdparty libraries?

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

回答by hagulu

presetName use "AVAssetExportPresetPassthrough" instead "AVAssetExportPresetLowQuality"

预设名称使用“AVAssetExportPresetPassthrough”代替“AVAssetExportPresetLowQuality”

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

回答by Daniel

MOV is very similar to MP4, you might be able to just change the extension and have it work, Windows Phone cant play .MOVS but can play mp4, all i did to get that to work is change the extension from .mov to .mp4 and it works fine, and this is from videos shot on the iphone...and if anything you can def try exporting with AVAssetExporter and try there is a file type in there for MP4 and M4A as you can see from the fileformat UTIs here

MOV 与 MP4 非常相似,您可以更改扩展名并使其正常工作,Windows Phone 无法播放 .MOVS 但可以播放 mp4,我所做的只是将扩展名从 .mov 更改为 .mp4并且它工作正常,这是来自在 iphone 上拍摄的视频......如果有的话,你可以尝试使用 AVAssetExporter 导出并尝试在那里有 MP4 和 M4A 的文件类型,正如你可以从这里的文件格式 UTI 中看到的

hope it helps

希望能帮助到你

回答by achermao

You need AVMutableCompositionto do this. Because Assetcan't be transcode to MP4 directly under iOS 5.0.

你需AVMutableComposition要这样做。因为Asset在iOS 5.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;
}

回答by CodeCracker

You can convert video in mp4 by AVAssets.

您可以通过 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;
  }
 }];

To easily convert video to mp4 use this link.

要轻松地将视频转换为 mp4,请使用此链接

You can also find sample project to convert video to mp4.

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

回答by Jigar Thakkar

Here is the code

这是代码

    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__).")
    }
}

回答by Hardik Mamtora

Use the below code

使用下面的代码

    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];

    }];

回答by rcpfuchs

just wanted to say that the URL can not be like

只想说网址不能像

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

It must be like

它必须像

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

Took me a while to figure that out :-)

我花了一段时间才弄清楚:-)