7


28

サーバーにビデオをアップロードすることは可能ですか? 私は画像が可能であることを知っています。 誰かが私を正しい方向に向けることができれば、それは素晴らしいことです。

ありがとう

4 Answer


17


  • 2015年8月に編集*

この答えは今真剣に時代遅れです。 これを書いている時点では、選択肢はそれほど多くなく、ビデオのサイズは比較的小さかった。 これを今見ているのであれば、これをもっと簡単にする `+ AFNetworking +`を使用します。 アップロードをすべてメモリに保持するのではなくファイルからストリーミングし、新しいAppleバックグラウンドアップロードタスクもサポートします。

こちらのドキュメント:https://github.com/AFNetworking/AFNetworking#creating-an-upload-task

 — --

はい、これは可能です、そして、これは私がそれについて行った方法です。

メディアピッカーが終了したときに実行される次の関数を実装します。

- (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];

    }

ポスト関数のために私は私が他のどこかから得たこのような何かを持っていた(すみません私はそれを見つけた場所がわからない):

- (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");
    }

}

上記のスニペットは、http postリクエストを作成して送信します。 きちんとしたエラー処理をしたい場合はそれを修正する必要があり、非同期アップロードを許可するライブラリの使用を検討する必要があります(githubにあります)。

また、上記のサーバーURLのport:3000に注目してください。デバッグ用のリクエストパラメータを見ることができるように、バグテストではデフォルトのポート3000の開発モードでRailsサーバーを起動するのが簡単です。

お役に立てれば


3


iOS 8以降、サードパーティのライブラリを使用する必要はなく、ファイルから直接ストリーミングすることができます。ファイルからロードしているときに大きなビデオをアップロードしようとすると、重大なメモリ不足エラーを解決できます。

// 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割り当て] initWithRequest:デリゲート要求:self startImmediately:YES];
  • iOS7は素晴らしいNSURLSeession / NSURLSessionUploadTaskコンボソリューションも提供します。これはファイルから直接ストリーミングできるだけでなく、タスクをiOSプロセスに委任することもできます。 それはもう少しコーディングを必要とし、私はそれをすべてここに書く時間がありません(あなたはそれをGoogleにすることができます)。

最も重要な部分は次のとおりです。

  1. バックグラウンドサポートでオーディオセッションを設定します。 - (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デリゲート:self delegateQueue:self.urlSessionQueue]; _urlSession.sessionDescription = @ "ログファイルのアップロード";

}

_urlSessionを返します。

} . タスクメソッドをアップロードします。

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){[setValue:self.uploadUserIdをリクエストします。 finalUrlString = [finalUrlString stringByAppendingFormat:@ "?id =%@"、self.uploadUserId]; }

[request setURL:[NSURL URLWithString:finalUrlString]]
;

/ *これは次のようになります(ファイル名を引用した場合にのみ機能します)。 filename = "fname.ext" * /

NSString * cdh = [NSString stringWithFormat:@ "添付ファイル;ファイル名= \"%@ \ ""、[ファイルパスlastPathコンポーネント]];
[request setValue:cdh forHTTPHeaderField:@"Content-Disposition"]
;

エラー= nil。 unsigned long fileSize = [[fm attributesOfItemAtPath:filePathエラー:

if(!error){

NSString * sizeInBytesAsString = [NSString stringWithFormat:@ "%lu"、fileSize]; [HTTPヘッダーヘッダのsetValue:sizeInBytesAsStringを要求する:@ "X-Content-Length"];

}

NSURL * fileUrl = [NSURL fileURLWithPath:filePath]; NSURLSessionUploadTask * uploadTask = [セッションuploadTaskWithRequest:request fromFile:fileUrl]; uploadTask.taskDescription = filePath;

uploadTaskを返します。

} . アップロード機能:[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。 スケジュールされたタスクを再開します。for(NSURLSessionUploadTask * uploadTasks内のタスク){

// MILogInfo(@ "%@の復元アップロードタスク%zu"、(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;} }

[タスクの再開]; }

// 2/2 まだスケジュールされていないタスク/ファイルを追加します。NSString * uploadFilePath = nil;

if(![tasks valueForKey:uploadFilePath]){NSURLSessionUploadTask * uploadTask = [self uploadTaskForFilePath:uploadFilePath session:_urlSession]; new_count; [uploadTask履歴書]; }

;]];
  1. バックグラウンドセッションにはUIApplecationデリゲートが必要です(AppDelegateコールバックが実装されています。

    • (void)application:(UIApplication *)アプリケーションのhandleEventsForBackgroundURLSession:(NSString *)識別子completionHandler:(void(^)())completionHandler \ {

NSLog(@ "バックグラウンドURLセッションではイベントを処理する必要があります:%@"、identifier); completionHandler();

}


2


UIImagePickerControllerを見てください。 3.0では、あなたがビデオを撮影するか既存のビデオを選ぶかを選択することができます。 ドキュメントによれば、あなたは映画の最大10分に制限されています:

http://developer.apple.com/IPhone/library/documentation/UIKit /参照/ UIImagePickerController_Class / UIImagePickerController / UIImagePickerController.html


0


NSURL * urlvideo = [info objectForKey:UIImagePickerControllerMediaURL];

NSString * urlString = [urlvideoパス];

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

NSString * str = [NSString stringWithFormat:@ "サーバーのURL"];

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"、[リクエストresponseStatusCode]);

NSLog(@ "responseStatusCode%@"、[request responseString]);