AVAssetExportSession
完成导出视频后。
我计划通过 Youtube 上传视频路径。
但是 [GDataUtilities MIMETypeForFileAtPath:path defaultMIMEType:@"video/mp4"];
它只接受 NSString
。
是否可以将 NSUrl 转换为视频文件路径的 NSString。
我尝试使用 NSString *path = [ExportoutputURL absoluteString];
但它崩溃了。
这是代码
- (void)exportDidFinish:(AVAssetExportSession*)session {
ExportoutputURL = session.outputURL;
_exporting = NO;
NSIndexPath *exportCellIndexPath = [NSIndexPath indexPathForRow:2 inSection:kProjectSection];
ExportCell *cell = (ExportCell*)[self.tableView cellForRowAtIndexPath:exportCellIndexPath];
cell.progressView.progress = 1.0;
[cell setProgressViewHidden:YES animated:YES];
[self updateCell:cell forRowAtIndexPath:exportCellIndexPath];
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
if ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:ExportoutputURL]) {
[library writeVideoAtPathToSavedPhotosAlbum:ExportoutputURL
completionBlock:^(NSURL *assetURL, NSError *error){
dispatch_async(dispatch_get_main_queue(), ^{
if (error) {
NSLog(@"writeVideoToAssestsLibrary failed: %@", error);
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:[error localizedDescription]
message:[error localizedRecoverySuggestion]
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alertView show];
[alertView release];
}
else {
_showSavedVideoToAssestsLibrary = YES;
ExportCell *cell = (ExportCell*)[self.tableView cellForRowAtIndexPath:exportCellIndexPath];
[cell setDetailTextLabelHidden:NO animated:YES];
[self updateCell:cell forRowAtIndexPath:exportCellIndexPath];
NSArray *modes = [[[NSArray alloc] initWithObjects:NSDefaultRunLoopMode, UITrackingRunLoopMode, nil] autorelease];
[self performSelector:@selector(hideCameraRollText) withObject:nil afterDelay:5.0 inModes:modes];
}
});
}];
}
[library release];
}
- (void)uploadVideoFile {
NSString *devKey = DEVELOPER_KEY;
GDataServiceGoogleYouTube *service = [self youTubeService];
[service setYouTubeDeveloperKey:devKey];
NSURL *url = [GDataServiceGoogleYouTube youTubeUploadURLForUserID:kGDataServiceDefaultUser];
// load the file data
NSString *path = [ExportoutputURL absoluteString];//[[NSBundle mainBundle] pathForResource:@"video_2451" ofType:@"mp4"];//[mFilePathField stringValue];
NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingAtPath:path];
NSString *filename = [path lastPathComponent];
// gather all the metadata needed for the mediaGroup
NSString *titleStr = @"Upload Test";//[mTitleField stringValue];
GDataMediaTitle *title = [GDataMediaTitle textConstructWithString:titleStr];
NSString *categoryStr = @"Entertainment";//[[mCategoryPopup selectedItem] representedObject];
GDataMediaCategory *category = [GDataMediaCategory mediaCategoryWithString:categoryStr];
[category setScheme:kGDataSchemeYouTubeCategory];
NSString *descStr = @"GData Description";//[mDescriptionField stringValue];
GDataMediaDescription *desc = [GDataMediaDescription textConstructWithString:descStr];
NSString *keywordsStr = @"RAGOpoR Demo";//[mKeywordsField stringValue];
GDataMediaKeywords *keywords = [GDataMediaKeywords keywordsWithString:keywordsStr];
BOOL isPrivate = NO;//([mPrivateCheckbox state] == NSOnState);
GDataYouTubeMediaGroup *mediaGroup = [GDataYouTubeMediaGroup mediaGroup];
[mediaGroup setMediaTitle:title];
[mediaGroup setMediaDescription:desc];
[mediaGroup addMediaCategory:category];
[mediaGroup setMediaKeywords:keywords];
[mediaGroup setIsPrivate:isPrivate];
NSString *mimeType = [GDataUtilities MIMETypeForFileAtPath:path
defaultMIMEType:@"video/mp4"];
// create the upload entry with the mediaGroup and the file
GDataEntryYouTubeUpload *entry;
entry = [GDataEntryYouTubeUpload uploadEntryWithMediaGroup:mediaGroup
fileHandle:fileHandle
MIMEType:mimeType
slug:filename];
SEL progressSel = @selector(ticket:hasDeliveredByteCount:ofTotalByteCount:);
[service setServiceUploadProgressSelector:progressSel];
GDataServiceTicket *ticket;
ticket = [service fetchEntryByInsertingEntry:entry
forFeedURL:url
delegate:self
didFinishSelector:@selector(uploadTicket:finishedWithEntry:error:)];
[self setUploadTicket:ticket];
GTMHTTPUploadFetcher *uploadFetcher = (GTMHTTPUploadFetcher *)[ticket objectFetcher];
}
错误 EXC_BAD_ACCESS 在
NSString *path = [ExportoutputURL absoluteString];
最佳答案
Is it possible to convert NSUrl in to NSString for video file path.
是的。向它发送 absoluteString
消息。
i have try to use NSString *path = [ExportoutputURL absoluteString]; but it crash.
如果您需要路径,请向 URL 发送一条 path
消息。表示 URL 的字符串通常不是有效路径;如果你想要一条路,请向它索取。
至于崩溃,并不代表absoluteString
有错。将 absoluteString
发送到 NSURL 对象是获取表示 URL 的 NSString 对象的正确方法。问题出在其他地方。
Error EXC_BAD_ACCESS at
NSString *path = [ExportoutputURL absoluteString];
这可能意味着 ExportoutputURL
指向的内容不是 nil
但也不是有效对象。它可能在某个时候指向了一个 NSURL 对象,但现在不是。
我的猜测是问题是这样的:
ExportoutputURL = session.outputURL;
您将 URL 分配给 ExportoutputURL
实例变量,但您不保留对象或创建自己的副本。因此,你不拥有这个对象,这意味着你没有让它存活。它可能随时终止,最有可能在此方法 (exportDidFinish:
) 返回之后。
崩溃是因为您稍后调用了 uploadVideoFile
,在 URL 对象已经死亡之后。您仍然有一个指向它的指针,但该对象不再存在,因此向它发送消息(任何消息)都会导致崩溃。
三种简单的解决方案:
- 在将 URL 对象分配给实例变量时保留它。
- 制作您自己的 URL 对象副本并将其分配给实例变量。
- 使用
strong
关键字或copy
关键字将ExportoutputURL
声明为属性,并将对象分配给属性,不是实例变量。这将调用属性的 setter ,如果您正确合成或实现它,它将为您保留或复制 URL。
无论哪种方式,您都将拥有该对象,这将使它保持事件状态,直到您释放它。因此,您需要在完成后释放它(在 dealloc
中,如果不是更早的话),这样您就不会泄露它。
这一切都假设您没有使用 ARC。如果您使用的是 Xcode 4.2 或更高版本,并且可能需要 iOS 4 或更高版本,您应该将您的项目迁移到 ARC,因为它使很多事情变得更加简单。如果您使用的是 ARC,则不需要保留或复制此对象,这意味着现在迁移到 ARC 是第四种解决方案(但肯定是更大规模的解决方案)。
关于objective-c - 如何将 NSUrl 转换为 NSString?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8867554/