Как преобразовать NSUrl в NSString?
После AVAssetExportSession
имеет полное экспортное видео.
У меня есть план обрезать Video Path для загрузки через 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];
Ответы
Ответ 1
Можно ли преобразовать NSUrl в NSString для пути к видеофайлу.
Да. Отправьте сообщение absoluteString
.
Я пытаюсь использовать NSString * path = [ExportoutputURL absoluteString]; но он разбился.
Если вам нужен путь, отправьте URL-адрес a path
. Строка, представляющая URL-адрес, обычно не является допустимым путем; если вам нужен путь, спросите его об этом.
Что касается аварии, это не означает, что absoluteString
неверно. Отправка absoluteString
объекту NSURL - это правильный способ получить объект NSString, который представляет URL-адрес. Проблема в другом месте.
Ошибка EXC_BAD_ACCESS при
NSString *path = [ExportoutputURL absoluteString];
Это, вероятно, означает, что ExportoutputURL
указывает на то, что не является nil
, но также не является допустимым объектом. В какой-то момент он мог указывать на объект NSURL, но это не так.
Я предполагаю, что проблема такова:
ExportoutputURL = session.outputURL;
Вы назначаете URL-адрес переменной экземпляра ExportoutputURL
, но вы не сохраняете объект или не создаете свою собственную копию. Следовательно, вы не являетесь владельцем этого объекта, а это значит, что вы не поддерживаете его. Он может умереть в любое время, скорее всего, после этого метода (exportDidFinish:
) вернется.
Авария происходит из-за того, что вы вызываете uploadVideoFile
позже, после того, как объект URL уже умер. У вас все еще есть указатель на него, но этот объект больше не существует, поэтому отправка ему сообщения - любое сообщение - вызывает сбой.
Существует три простых решения:
- Сохраняйте объект URL, когда вы назначаете его переменной экземпляра.
- Создайте собственную копию объекта URL и назначьте ее переменной экземпляра.
- Объявить
ExportoutputURL
как свойство, либо с ключевым словом strong
, либо с ключевым словом copy
, и назначить объект этому свойству, а не переменной экземпляра. Это вызовет средство настройки свойств, которое, если вы его синтезируете или реализуете правильно, сохранит или скопирует URL-адрес для вас.
В любом случае, вы будете владеть объектом, и это будет поддерживать его до тех пор, пока вы его не отпустите. Соответственно, вам нужно будет освободить его, когда вы закончите с ним (в dealloc
, если не раньше), чтобы вы не пропустили его.
Все это предполагает, что вы не используете ARC. Если вы используете Xcode 4.2 или новее и можете потребовать iOS 4 или более позднюю версию, вы должны перенести свой проект на ARC, поскольку он делает так много вещей намного проще. Вам не нужно будет сохранять или копировать этот объект, если вы используете ARC, а это значит, что переход на ARC теперь является четвертым решением (но, конечно, более крупным).
Ответ 2
NSString *path = [[NSString alloc] initWithString:[url path]]; ?
Ответ 3
Используйте absolutePath
или path
, как указано Miek и Nepster. Расширяясь в своих ответах, разница между ложью в префиксе.
NSString* string1 = [url absoluteString]; // @"file:///Users/jackbrown/Music/song name.mp3"
NSString* string2 = [url path]; // @"/Users/jackbrown/Music/song name.mp3"`
Ответ 4
Просто вы можете сделать это вот так.
NSString *myString = [myURL absoluteString];