3

ユーザーがビデオをFTPサーバーにアップロードするためのAPPに取り組んでいます

これまでのところ、すべてがほぼ完了していますが、ユーザーがビデオ (.MOV) をアップロードした後、ファイルを開いて再生できないという問題が 1 つあります。

QuickTime Player が返すエラー メッセージは、「ムービーのファイル形式が認識されないため開けません」です。

私のコードでは、ALAssetsLibrady を使用してユーザーが動画を選択できるようにしています。

次に、ビデオを ALAsset オブジェクトにロードします。アップロードを開始する前に、ビデオを ALAsset から NSInputStream オブジェクトにロードします。コードは次のとおりです。

ALAssetRepresentation *rep = [currentAsset defaultRepresentation];
Byte *buffer = (Byte*)malloc(rep.size);
NSUInteger buffered = [rep getBytes:buffer fromOffset:0.0 length:rep.size error:nil];
NSData *data = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];

iStream = [NSInputStream inputStreamWithData:data];
[iStream open];

次のステップは、NSOutputStream を設定して開き、次のコードでアップロード操作を処理することです。

- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
{
switch (eventCode) {
    case NSStreamEventNone:
    {
        break;
    }
    case NSStreamEventOpenCompleted:
    {
        //opened connection
        NSLog(@"opened connection");
        break;
    }
    case NSStreamEventHasBytesAvailable:
    {
        // should never happen for the output stream
        [self stopSendWithStatus:@"should never happen for the output stream"];
        break;
    }
    case NSStreamEventHasSpaceAvailable:
    {
        // If we don't have any data buffered, go read the next chunk of data.
        NSInteger bufferSize = 65535;
        uint8_t *buffer = malloc(bufferSize);

        if (bufferOffset == bufferLimit) {
            NSInteger bytesRead = [iStream read:buffer maxLength:bufferSize];

            if (bytesRead == -1) {
                [self stopSendWithStatus:@"file read error"];
            } else if (bytesRead == 0) {
                [self stopSendWithStatus:nil];
            } else {
                bufferOffset = 0;
                bufferLimit  = bytesRead;
            }
        }

        // If we're not out of data completely, send the next chunk.

        if (bufferOffset != bufferLimit) {
            NSInteger bytesWritten = [oStream write:&buffer[bufferOffset] maxLength:bufferLimit - bufferOffset];
            if (bytesWritten == -1) {
                [self stopSendWithStatus:@"file write error"];
            } else {
                bufferOffset += bytesWritten;
            }
        }

        //NSLog(@"available");
        break;
    }
    case NSStreamEventErrorOccurred:
    {
        //stream open error
        [self stopSendWithStatus:[[aStream streamError] description]];
        break;
    }
    case NSStreamEventEndEncountered:   //ignore
        NSLog(@"end");
        break;
}
}

エラーは発生しません。ビデオ ファイルは正しいファイル サイズと名前で FTP にアップロードされますが、開くことができません。

手がかりを知っている人はいますか?

4

3 に答える 3

1

ALAsset オブジェクトをストリーミングするための NSInputStream 実装を作成しました - POSInputStreamLibrary。ソリューションとして 1GB のビデオ全体をメモリに読み込むのではなく、代わりにチャンクでムービーを読み込みます。もちろん、POSBlobInputStream の機能はこれだけではありません。詳細については、私の GitHub リポジトリを参照してください。

于 2014-03-15T09:48:32.963 に答える
0

これはおそらくあなたが探している答えではないことを私は知っていますが、ユーザーがあなたのウェブサーバーにファイルをアップロードできるようにするためにFTP経由の直接接続を使用するべきではありません。それは安全ではなく、RESTと比較して遅いです。

代わりに、アップロードを処理するためのphpを少し作成し、RESTを介してアプリからファイルをPOSTしてみませんか?ここ:

$uploaddir = 'uploads/';
$file = basename($_FILES['file']['name']);
$uploadfile = $uploaddir . $file;

また、AFNetworkingを使用してPOSTリクエストを処理することをお勧めしますhttp://afnetworking.com/

于 2013-01-31T08:56:16.183 に答える
0

まず、以外に変換ALAssetしてメモリ容量を減らすつもりだったと思います。メモリ付き。NSInputStreamNSDataNSDataNSDataNSInputStreamNSData

したがって、Streamメモリの負荷を軽減するためにビデオを転送する場合 (または、ビデオが最大 2GB 以上であるため選択の余地がない場合)、CFStreamCreateBoundPairチャンクごとにファイルをアップロードするために使用する必要があります。下記のApple iOS Developer Libraryを参照してください。 .

構築されたデータの大きなブロックの場合、CFStreamCreateBoundPair を呼び出してストリームのペアを作成してから、setHTTPBodyStream: メソッドを呼び出して、NSMutableURLRequest にこれらのストリームの 1 つを本体コンテンツのソースとして使用するように指示します。もう一方のストリームに書き込むことで、一度に 1 つずつデータを送信できます。

私はgithubでviaに変換する迅速なバージョンを持っていALAssetます。重要な点は、書かれたドキュメントとまったく同じです。別の参照はこの質問です。NSInputStreamCFStreamCreateBoundPair

お役に立てば幸いです。

于 2016-05-30T02:11:02.777 に答える