Trim Video Always Fail When Use Avassetexportpresetpassthrough

Trim video always fail when use AVAssetExportPresetPassthrough

I wrote anwer in another question, they have the same problem, but it different way. That's how I solved the problem
https://stackoverflow.com/a/70294032/7217629

How to trim video with AVAssetReader and AVAssetWriter

AVAssetReader has a property named timeRange - you can specify time range which you need to proceed, so this will allow you to trim your output file

Exporting mp4 through AVAssetExportSession fails

Seems like converting the AVAsset instance in a AVMutableComposition did the trick. If, please, anyone knows the reason why this works let me know.

This is the new _getDataFor(_:completion:) method implementation

func _getDataFor(_ item: AVPlayerItem, completion: @escaping (Data?) -> ()) {
guard item.asset.isExportable else {
completion(nil)
return
}

let composition = AVMutableComposition()
let compositionVideoTrack = composition.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: CMPersistentTrackID(kCMPersistentTrackID_Invalid))
let compositionAudioTrack = composition.addMutableTrack(withMediaType: AVMediaTypeAudio, preferredTrackID: CMPersistentTrackID(kCMPersistentTrackID_Invalid))

let sourceVideoTrack = item.asset.tracks(withMediaType: AVMediaTypeVideo).first!
let sourceAudioTrack = item.asset.tracks(withMediaType: AVMediaTypeAudio).first!
do {
try compositionVideoTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, item.duration), of: sourceVideoTrack, at: kCMTimeZero)
try compositionAudioTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, item.duration), of: sourceAudioTrack, at: kCMTimeZero)
} catch(_) {
completion(nil)
return
}

let compatiblePresets = AVAssetExportSession.exportPresets(compatibleWith: composition)
var preset: String = AVAssetExportPresetPassthrough
if compatiblePresets.contains(AVAssetExportPreset1920x1080) { preset = AVAssetExportPreset1920x1080 }

guard
let exportSession = AVAssetExportSession(asset: composition, presetName: preset),
exportSession.supportedFileTypes.contains(AVFileTypeMPEG4) else {
completion(nil)
return
}

var tempFileUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("temp_video_data.mp4", isDirectory: false)
tempFileUrl = URL(fileURLWithPath: tempFileUrl.path)

exportSession.outputURL = tempFileUrl
exportSession.outputFileType = AVFileTypeMPEG4
let startTime = CMTimeMake(0, 1)
let timeRange = CMTimeRangeMake(startTime, item.duration)
exportSession.timeRange = timeRange

exportSession.exportAsynchronously {
print("\(tempFileUrl)")
print("\(exportSession.error)")
let data = try? Data(contentsOf: tempFileUrl)
_ = try? FileManager.default.removeItem(at: tempFileUrl)
completion(data)
}
}

EXC_BAD_ACCESS with AVAssetExportSession and AVMutableComposition

My crash was a simple issue. The bigger problem I had was using the wrong filename extension. I'm now using .mp4, AVFileTypeQuickTimeMovie and AVAssetExportPresetPassthrough.

How to trim the video file and convert to 15 seconds video with iOS SDK?

Objective-C

-(void)cropVideo:(NSURL*)videoToTrimURL{
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:videoToTrimURL options:nil];
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetHighestQuality];

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *outputURL = paths[0];
NSFileManager *manager = [NSFileManager defaultManager];
[manager createDirectoryAtPath:outputURL withIntermediateDirectories:YES attributes:nil error:nil];
outputURL = [outputURL stringByAppendingPathComponent:@"output.mp4"];
// Remove Existing File
[manager removeItemAtPath:outputURL error:nil];

exportSession.outputURL = [NSURL fileURLWithPath:outputURL];
exportSession.shouldOptimizeForNetworkUse = YES;
exportSession.outputFileType = AVFileTypeQuickTimeMovie;
CMTime start = CMTimeMakeWithSeconds(1.0, 600); // you will modify time range here
CMTime duration = CMTimeMakeWithSeconds(15.0, 600);
CMTimeRange range = CMTimeRangeMake(start, duration);
exportSession.timeRange = range;
[exportSession exportAsynchronouslyWithCompletionHandler:^(void)
{
switch (exportSession.status) {
case AVAssetExportSessionStatusCompleted:
[self writeVideoToPhotoLibrary:[NSURL fileURLWithPath:outputURL]];
NSLog(@"Export Complete %d %@", exportSession.status, exportSession.error);
break;
case AVAssetExportSessionStatusFailed:
NSLog(@"Failed:%@",exportSession.error);
break;
case AVAssetExportSessionStatusCancelled:
NSLog(@"Canceled:%@",exportSession.error);
break;
default:
break;
}

//[exportSession release];
}];
}

In Swift 4.0

    static func cropVideo(atURL url:URL) {
let asset = AVURLAsset(url: url)
let exportSession = AVAssetExportSession.init(asset: asset, presetName: AVAssetExportPresetHighestQuality)!
var outputURL = URL(string:NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).last!)

let fileManager = FileManager.default
do {
try fileManager.createDirectory(at: outputURL!, withIntermediateDirectories: true, attributes: nil)
} catch {

}

outputURL?.appendPathComponent("output.mp4")
// Remove existing file
do {
try fileManager.removeItem(at: outputURL!)
}
catch {

}

exportSession.outputURL = outputURL
exportSession.shouldOptimizeForNetworkUse = true
exportSession.outputFileType = AVFileTypeQuickTimeMovie
let start = CMTimeMakeWithSeconds(1.0, 600) // you will modify time range here
let duration = CMTimeMakeWithSeconds(15.0, 600)
let range = CMTimeRangeMake(start, duration)
exportSession.timeRange = range
exportSession.exportAsynchronously {
switch(exportSession.status) {
case .completed: break
//
case .failed: break
//
case .cancelled: break
//
default: break
}
}
}

Failed to initialize an AVAssetExportSession (iPhone XS, XR, XMax)

Apparently it's an apple bug... https://bugreport.apple.com/web/?problemID=44701489
Will report back once the original bug is closed.

EDIT: This issue has been fixed by Apple in iOS 10.1 SDK. You just update your xcode to 10.1.

AVAssetExportSession giving me a green border on right and bottom of output video

Usually green lines appear after video cropping, problem is in video renderSize width, it should be multiply of 16.

Here some links about this:
apple 1
apple 2



Related Topics



Leave a reply



Submit