3

簡単な手順のように見えますが、今では 3 時間試していますが、成功しません。私はおそらく本当にばかげた何かを見逃しています。

だから、私はインターネットからビデオをダウンロードするこのアプリを持っています。ローカル URL を提供して再生できるため、ビデオはローカルに正しく保存されます。しかし、動画をカメラロールにコピーできません。これが私がすることです:

    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
    ALAssetsLibraryWriteVideoCompletionBlock videoWriteCompletionBlock =
    ^(NSURL *newURL, NSError *error) {
        if (error) {
            NSLog( @"Error writing image with metadata to Photo Library: %@", error );
        } else {
            NSLog( @"Wrote image with metadata to Photo Library %@", newURL.absoluteString);
        }
    };

    NSLog(@"file %@", localPath);
    NSURL *url = [NSURL fileURLWithPath:localPath isDirectory:NO];
    [library writeVideoAtPathToSavedPhotosAlbum:url
                                completionBlock:videoWriteCompletionBlock];

しかし、私が得る出力は次のとおりです。

2013-07-24 00:13:32.094 App[1716:907] file /var/mobile/Applications/70C18C4E-9F97-4A6A-B63E-1BD19961F010/Documents/downloaded_video.mp4
2013-07-24 00:13:32.374 App[1716:907] Wrote image with metadata to Photo Library (null)

もちろん、ファイルはカメラロールに保存されません。これは、私が使用しているデバイスと互換性のある単純な mp4 です (つまり、保存できるはずです)。

正直なところ、何をすべきかわかりません。どんなヒントでも大歓迎です。ありがとう

4

3 に答える 3

9

私はあなたのための回避策を見つけたかもしれません。を試しましたAVAssetExportSessionか?

以下のサンプルでは、​​画面に 2 つのボタンを持つ単純なアプリを作成しました。1 つは を呼び出しますonSaveBtn:。これは、アプリのリソース バンドルにあるビデオの URL を取得し、それをユーザーの保存済み写真アルバムに保存するだけです。(ただし、私の場合、私の動画はYESから返されvideoAtPathIsCompatibleWithSavedPhotosAlbum:ます。それ以外の方法で返されない動画はありませんでした。)

2 番目のボタンは に接続されてonExportBtn:おり、保存するビデオを取得して を作成しAVAssetExportSession、ビデオを一時ディレクトリにエクスポートしてから、エクスポートしたビデオを保存済みの写真アルバムにコピーします。エクスポートに時間がかかるため、この方法は単純なコピーよりも時間がかかりますが、これは別の方法である可能性があります - の結果を確認し、videoAtPathIsCompatibleWithSavedPhotosAlbum:場合YESはアルバムに直接コピーしてください。それ以外の場合は、ビデオをエクスポートしてからコピーします。

互換性コールに戻らないビデオ ファイルがなければ、NOこれがうまくいくとは 100% 確信が持てませんが、試してみる価値はあります。

また、この質問 を確認することもできます。この質問では、使用している可能性のあるデバイスで互換性のあるビデオ フォーマットを調べています。

#import <AVFoundation/AVFoundation.h>
#import <AssetsLibrary/AssetsLibrary.h>

- (IBAction)onSaveBtn:(id)sender
{
    NSURL *srcURL = [[NSBundle mainBundle] URLForResource:@"WP_20121214_001" withExtension:@"mp4"];
    [self saveToCameraRoll:srcURL];
}

- (IBAction)onExportBtn:(id)sender
{
    NSURL *srcURL = [[NSBundle mainBundle] URLForResource:@"WP_20121214_001" withExtension:@"mp4"];
    AVAsset *srcAsset = [AVAsset assetWithURL:srcURL];

    // create an export session
    AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:srcAsset presetName:AVAssetExportPresetHighestQuality];

    // Export the file to a tmp dir
    NSString *fileName = [srcURL lastPathComponent];
    NSString *tmpDir = NSTemporaryDirectory();
    NSURL *tmpURL = [NSURL fileURLWithPath:[tmpDir stringByAppendingPathComponent:fileName]];

    exportSession.outputURL = tmpURL;
    exportSession.outputFileType = AVFileTypeQuickTimeMovie;

    [exportSession exportAsynchronouslyWithCompletionHandler:^{       
        // now copy the tmp file to the camera roll
        switch ([exportSession status]) {
            case AVAssetExportSessionStatusFailed:
                NSLog(@"Export failed: %@", [[exportSession error] localizedDescription]);
                break;
            case AVAssetExportSessionStatusCancelled:
                NSLog(@"Export canceled");
                break;
            case AVAssetExportSessionStatusCompleted:
                NSLog(@"Export successful");
                [self saveToCameraRoll:exportSession.outputURL];
                break;
            default:
                break;
        }
    }];
}

- (void) saveToCameraRoll:(NSURL *)srcURL
{
    NSLog(@"srcURL: %@", srcURL);

    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
    ALAssetsLibraryWriteVideoCompletionBlock videoWriteCompletionBlock =
    ^(NSURL *newURL, NSError *error) {
        if (error) {
            NSLog( @"Error writing image with metadata to Photo Library: %@", error );
        } else {
            NSLog( @"Wrote image with metadata to Photo Library %@", newURL.absoluteString);
        }
    };

    if ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:srcURL])
    {
        [library writeVideoAtPathToSavedPhotosAlbum:srcURL
                                    completionBlock:videoWriteCompletionBlock];
    }
}
于 2013-07-24T17:12:42.080 に答える
0

ここに短い答えがあります。

私の場合、AFNetworking を使用して URL からビデオをダウンロードし、ダウンロード操作の downloadCompletedBlock でresponseObjectダウンロード ファイルを返します。ログresponseObjectに記録すると、ダウンロードしたビデオの完全なファイル パスが返されます。

動画をダウンロードする別の方法を使用している場合はresponseObject、おそらく通常のNSSearchPathForDirectoriesInDomains方法で、動画の完全なファイル パスに置き換えるだけです。

アプリケーションのローカル ファイル ディレクトリにあるビデオをカメラ ロールにエクスポートするために使用するスニペットを次に示します。

NSURL *responseObjectPath = [NSURL URLWithString:responseObject];
// If video is compatible with Camera Roll
if ([[ALAssetsLibrary new] videoAtPathIsCompatibleWithSavedPhotosAlbum:responseObjectPath])
{
    // Export to Camera Roll
    [[ALAssetsLibrary new] writeVideoAtPathToSavedPhotosAlbum:responseObjectPath completionBlock:nil];
}
else
{
    NSLog(@"Incompatible File Type");
}

乾杯!

于 2014-05-01T14:50:30.623 に答える
0

ブロックへの URL を提供している場所。私はあなたがこのようにする必要があると思います..

NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL];

ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library writeVideoAtPathToSavedPhotosAlbum:videoURL completionBlock:^(NSURL *assetURL, NSError *error){
       /*notify of completion*/
       NSLog(@"AssetURL: %@",assetURL);
       NSLog(@"Error: %@",error);
       if (!error) {
            //video saved

       }else{
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:error.domain delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
                [alert show];
                [alert release];
       }

}];

ここで URL を変更できます。私は imagePickerController に使用しました。

于 2013-07-24T06:16:42.090 に答える