2009-06-30 10 views
7

¿Es posible cargar video en un servidor? Sé que las imágenes son posibles. Si alguien puede simplemente señalarme en la dirección correcta, sería increíble.Carga de video con iPhone

Gracias

+0

¿está buscando a Uplo video publicitario tomado por el nuevo iPhone 3GS o video almacenado localmente en el dispositivo ?? Recuerde que no hay forma de acceder al sistema de archivos global del iPhone, por lo que esta última opción no es factible. – zpesk

Respuesta

17

Editado Ago 2015

Esta respuesta es ahora muy desfasados. En el momento de escribir, no había muchas opciones y los videos eran relativamente pequeños. Si está buscando hacerlo ahora, usaría AFNetworking, lo cual hace que esto sea mucho más simple. Transmitirá la carga desde el archivo en lugar de mantenerlo todo en la memoria, y también es compatible con la nueva tarea de carga en segundo plano de Apple.

Docs aquí: https://github.com/AFNetworking/AFNetworking#creating-an-upload-task

-

Si esto es posible, y así es como fui al respecto.

Implemente la siguiente función que se ejecuta cuando el selector de medios finaliza.

- (NSData *)generatePostDataForData:(NSData *)uploadData 
{ 
    // Generate the post header: 
    NSString *post = [NSString stringWithCString:"--AaB03x\r\nContent-Disposition: form-data; name=\"upload[file]\"; filename=\"somefile\"\r\nContent-Type: application/octet-stream\r\nContent-Transfer-Encoding: binary\r\n\r\n" encoding:NSASCIIStringEncoding]; 

    // Get the post header int ASCII format: 
    NSData *postHeaderData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; 

    // Generate the mutable data variable: 
    NSMutableData *postData = [[NSMutableData alloc] initWithLength:[postHeaderData length] ]; 
    [postData setData:postHeaderData]; 

    // Add the image: 
    [postData appendData: uploadData]; 

    // Add the closing boundry: 
    [postData appendData: [@"\r\n--AaB03x--" dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]]; 

    // Return the post data: 
    return postData; 
} 


- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{ 

    //assign the mediatype to a string 
    NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType]; 

    //check the media type string so we can determine if its a video 
    if ([mediaType isEqualToString:@"public.movie"]){ 
     NSLog(@"got a movie"); 
     NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL]; 
     NSData *webData = [NSData dataWithContentsOfURL:videoURL]; 
     [self post:webData]; 
     [webData release]; 

    } 

para la función de post que tenía algo como esto lo que me dieron desde otro lugar (lo siento, no sé por dónde lo encontré):

- (void)post:(NSData *)fileData 
{ 

    NSLog(@"POSTING"); 

    // Generate the postdata: 
    NSData *postData = [self generatePostDataForData: fileData]; 
    NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]]; 

    // Setup the request: 
    NSMutableURLRequest *uploadRequest = [[[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://www.example.com:3000/"] cachePolicy: NSURLRequestReloadIgnoringLocalCacheData timeoutInterval: 30 ] autorelease]; 
    [uploadRequest setHTTPMethod:@"POST"]; 
    [uploadRequest setValue:postLength forHTTPHeaderField:@"Content-Length"]; 
    [uploadRequest setValue:@"multipart/form-data; boundary=AaB03x" forHTTPHeaderField:@"Content-Type"]; 
    [uploadRequest setHTTPBody:postData]; 

    // Execute the reqest: 
    NSURLConnection *conn=[[NSURLConnection alloc] initWithRequest:uploadRequest delegate:self]; 
    if (conn) 
    { 
     // Connection succeeded (even if a 404 or other non-200 range was returned). 
     NSLog(@"sucess"); 
     UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Got Server Response" message:@"Success" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; 
     [alert show]; 
     [alert release]; 
    } 
    else 
    { 
     // Connection failed (cannot reach server). 
     NSLog(@"fail"); 
    } 

} 

El fragmento anterior se basa la solicitud HTTP POST y se somete eso. Tendrá que modificarlo si desea un manejo de errores decente y considerar el uso de una biblioteca que permita la carga asíncrona (hay uno en github)

También tenga en cuenta el puerto: 3000 en la URL del servidor anterior, me resultó fácil realizar pruebas para iniciar un servidor rieles en su puerto por defecto 3000 en el modo de desarrollo por lo que podía ver los parámetros de la petición para propósitos de depuración

espero que esto ayude

+0

Genial, voy a probar esto, gracias amigo –

+0

No Probs. Una cosa a tener en cuenta es que el SDK actual no parece darle acceso al video de resolución completa, ya que se sincronizaría con iTunes. Mis pruebas mostraron un tamaño máximo de video de 480x360. Si puede encontrar un trabajo alternativo por favor háganos saber. gracias – ADAM

+0

¿Esta colección de basura falta? – jocull

0
NSURL *urlvideo = [info objectForKey:UIImagePickerControllerMediaURL]; 

NSString *urlString=[urlvideo path]; 

NSLog(@"urlString=%@",urlString); 

NSString *str = [NSString stringWithFormat:@"you url of server"]; 

NSURL *url = [NSURL URLWithString:[str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; 


ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url]; 

[request setFile:urlString forKey:@"key foruploadingFile"]; 

[request setRequestMethod:@"POST"]; 

[request setDelegate:self]; 

[request startSynchronous]; 

NSLog(@"responseStatusCode %i",[request responseStatusCode]); 

NSLog(@"responseStatusCode %@",[request responseString]); 
+1

Puede enviar un archivo de video capturado por el controlador uiimagepicker mediante el uso de este código. Y tienes que tomar el framework assihttprequest de github – chinni

3

Desde iOS8 no hay necesidad de utilizar las bibliotecas 3 ª parte y se puede transmitir video directamente desde el archivo que resuelve c rucial error de memoria cuando intenta subir videos más grandes, mientras que cargarlos desde un archivo:

// If video was returned by UIImagePicker ... 
NSURL *videoUrl = [_videoDictionary objectForKey:UIImagePickerControllerMediaURL]; 

NSMutableURLRequest *request =[[NSMutableURLRequest alloc] init]; 
[request setURL:[NSURL URLWithString:VIDEO_UPLOAD_LINK]]; 
[request addValue:@"video" forHTTPHeaderField: @"Content-Type"]; 
[request setHTTPMethod:@"POST"]; 

NSInputStream *inputStream = [[NSInputStream alloc] initWithFileAtPath:[videoUrl path]]; 
[request setHTTPBodyStream:inputStream]; 

self.uploadConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES]; 

iOS7 también ofrece/solución de gran NSURLSeession NSURLSessionUploadTask combinado, que no sólo te permite reproducir contenido directamente desde el archivo, pero también puede delegar tareas al proceso de iOS, lo que permitirá que la carga termine incluso cuando se cierre su aplicación. Requiere un poco más de codificación y no tengo tiempo para escribirlo todo aquí (puedes buscarlo en Google).

Estas son las partes más importantes:

  1. Confugure sesión de audio en el fondo de la ayuda:

    - (NSURLSession *) urlSession {

    if (!_urlSession) { 
    
    
        NSDictionary *infoDict = [[NSBundle mainBundle] infoDictionary]; 
        NSString *bundleId = infoDict[@"CFBundleIdentifier"]; 
    
        NSString *label = [NSString stringWithFormat:@"ATLoggerUploadManager_%@", bundleId]; 
    
        NSURLSessionConfiguration *conf = (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_7_1) ? [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:label] : [NSURLSessionConfiguration backgroundSessionConfiguration:label]; 
        conf.allowsCellularAccess = NO; 
    
        _urlSession = [NSURLSession sessionWithConfiguration:conf delegate:self delegateQueue:self.urlSessionQueue]; 
        _urlSession.sessionDescription = @"Upload log files"; 
    
    } 
    
    return _urlSession; 
    

    }

  2. Subir método de tarea:

    - (NSURLSessionUploadTask *) uploadTaskForFilePath: (NSString *) sesión rutaArchivo: (NSURLSession *) sesión {

    NSFileManager *fm = [NSFileManager defaultManager]; 
    NSError *error = nil; 
    
    // Consruct request: 
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; 
    [request setHTTPMethod:@"POST"]; 
    NSString *finalUrlString = [self.uploadURL absoluteString]; 
    
    if (self.uploadUserId) { 
        [request setValue:self.uploadUserId forHTTPHeaderField:@"X-User-Id"]; 
        finalUrlString = [finalUrlString stringByAppendingFormat:@"?id=%@", self.uploadUserId]; 
    } 
    
    [request setURL:[NSURL URLWithString:finalUrlString]]; 
    
    /* 
    It looks like this (it only works if you quote the filename): 
    Content-Disposition: attachment; filename="fname.ext" 
    */ 
    
    NSString *cdh = [NSString stringWithFormat:@"attachment; filename=\"%@\"", [filePath lastPathComponent]]; 
    [request setValue:cdh forHTTPHeaderField:@"Content-Disposition"]; 
    
    error = nil; 
    unsigned long fileSize = [[fm attributesOfItemAtPath:filePath error:&error] fileSize]; 
    
    if (!error) { 
    
        NSString *sizeInBytesAsString = [NSString stringWithFormat:@"%lu", fileSize]; 
        [request setValue:sizeInBytesAsString forHTTPHeaderField:@"X-Content-Length"]; 
    
    } 
    
    NSURL *fileUrl = [NSURL fileURLWithPath:filePath]; 
    NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromFile:fileUrl]; 
    uploadTask.taskDescription = filePath; 
    
    return uploadTask; 
    

    }

  3. Subir función:

    [self.urlSession getTasksWithCompletionHandler:^(* NSArray dataTasks, NSArray * uploadTasks, NSArray * downloadTasks) {

    NSMutableDictionary *tasks = [NSMutableDictionary new]; 
    
        int resumed_running_count = 0; 
        int resumed_not_running_count = 0; 
        int new_count = 0; 
        // 1/2. Resume scheduled tasks: 
        for(NSURLSessionUploadTask *task in uploadTasks) { 
    
         //MILogInfo(@"Restored upload task %zu for %@", (unsigned long)task.taskIdentifier, task.originalRequest.URL); 
    
         if (task.taskDescription) { 
    
          [tasks setObject:task forKey:task.taskDescription]; 
         } 
    
         BOOL isRunning = (task.state == NSURLSessionTaskStateRunning); 
         if (!isRunning) { 
    
          resumed_not_running_count++; 
         }else{ 
          resumed_running_count++; 
         } 
    
         [task resume]; 
        } 
    
        // 2/2. Add tasks/files not scheduled yet: 
        NSString *uploadFilePath = nil; 
    
         // already uploading: 
         if (![tasks valueForKey:uploadFilePath]) { 
          NSURLSessionUploadTask *uploadTask = [self uploadTaskForFilePath:uploadFilePath session:_urlSession]; 
          new_count++; 
          [uploadTask resume]; 
         } 
    
    }]; 
    
  4. sesión Antecedentes requiere UIApplecation delegado (AppDelegate de devolución de llamada en práctica:

    • (void) aplicación: (UIApplication *) handleEventsForBackgroundURLSession aplicación: (NSString *) identificador completionHandler: (void (^)()) completionHandler {

      NSLog(@"Background URL session needs events handled: %@", identifier); 
      completionHandler(); 
      

      }

Cuestiones relacionadas