Une fois que AVAssetExportSession
a terminé l'exportation de la vidéo. J'ai l'intention de mettre le chemin vidéo à télécharger via Youtube. mais [GDataUtilities MIMETypeForFileAtPath:path defaultMIMEType:@"video/mp4"];
il accepte uniquement NSString
. Est-il possible de convertir NSUrl en NSString pour le chemin du fichier vidéo.
j'ai essayé d'utiliser NSString *path = [ExportoutputURL absoluteString];
mais ça plante.
Voici le code
- (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];
}
Erreur EXC_BAD_ACCESS à
NSString *path = [ExportoutputURL absoluteString];
Est-il possible de convertir NSUrl en NSString pour le chemin du fichier vidéo.
Oui. Envoyez-lui un message absoluteString
.
j'ai essayé d'utiliser NSString * path = [ExportoutputURL absolueString]; mais ça plante.
Si vous voulez un chemin, envoyez à l'URL un message path
. Une chaîne représentant une URL n'est généralement pas un chemin valide; si vous voulez un chemin, demandez-en un.
Quant au crash, cela ne signifie pas que absoluteString
est incorrect. L'envoi de absoluteString
à un objet NSURL est la bonne façon d'obtenir un objet NSString qui représente l'URL. Le problème est ailleurs.
Erreur EXC_BAD_ACCESS à
NSString *path = [ExportoutputURL absoluteString];
Cela signifie probablement que ExportoutputURL
pointe vers quelque chose qui n'est pas nil
mais n'est pas non plus un objet valide. Il aurait pu pointer vers un objet NSURL à un moment donné, mais ce n'est pas le cas maintenant.
Je suppose que le problème est le suivant:
ExportoutputURL = session.outputURL;
Vous affectez l'URL à la variable d'instance ExportoutputURL
, mais vous ne conservez pas l'objet ou ne faites pas votre propre copie. Par conséquent, vous ne possédez pas cet objet, ce qui signifie que vous ne le gardez pas en vie. Il peut mourir à tout moment, très probablement après cette méthode (exportDidFinish:
) Retour.
Le plantage est dû au fait que vous appellerez uploadVideoFile
plus tard, une fois que l'objet URL est déjà mort. Vous avez toujours un pointeur dessus, mais cet objet n'existe plus, donc lui envoyer un message —any message — provoque un plantage.
Il existe trois solutions simples:
ExportoutputURL
en tant que propriété, avec le mot clé strong
ou le mot clé copy
, et affectez l'objet à la propriété, not la variable d'instance . Cela appellera le setter de la propriété qui, si vous le synthétisez ou l'implémentez correctement, conservera ou copiera l'URL pour vous.Quoi qu'il en soit, vous serez propriétaire de l'objet, et cela le maintiendra en vie jusqu'à ce que vous le libériez. En conséquence, vous devrez le libérer lorsque vous en aurez terminé (dans dealloc
, sinon plus tôt), afin de ne pas le divulguer.
Tout cela suppose que vous n'utilisez pas ARC. Si vous utilisez Xcode 4.2 ou version ultérieure, et pouvez nécessiter iOS 4 ou version ultérieure, vous devez migrer votre projet vers ARC, car cela simplifie beaucoup les choses. Vous n'auriez pas besoin de conserver ou de copier cet objet si vous utilisiez ARC, ce qui signifie que la migration vers ARC est maintenant une quatrième solution (mais certainement à plus grande échelle).
Utilisez absolutePath
ou path
comme mentionné par Miek et Nepster. S'étendant sur leurs réponses, la différence entre réside dans le préfixe.
NSString* string1 = [url absoluteString]; // @"file:///Users/jackbrown/Music/song name.mp3"
NSString* string2 = [url path]; // @"/Users/jackbrown/Music/song name.mp3"`
NSString *path = [[NSString alloc] initWithString:[url path]]; ?
Vous pouvez simplement le faire comme ça.
NSString *myString = [myURL absoluteString];
Utilisez ceci. Je pense que cela vous aidera.
Dans l'objectif C
NSString *testString = testUrl.absoluteString;
Dans Swift
var testString : String = testUrl.absoluteString