博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
AVAssetExportSession 音视频的剪辑,以及格式的装换
阅读量:6077 次
发布时间:2019-06-20

本文共 4472 字,大约阅读时间需要 14 分钟。

hot3.png

    //第一种方式

    

    //asset生成必须为文件的url,而且是本地

    AVAsset *mediaAsset = _player.currentItem.asset;

    

    //AVMutableComposition 可以进行音视频的组合

    

    AVAssetExportSession *es = [[AVAssetExportSession alloc] initWithAsset:mediaAsset presetName:AVAssetExportPresetPassthrough];

    

    NSString *outPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"out.mov"];

    

    NSFileManager *fileManager = [NSFileManager defaultManager];

    [fileManager removeItemAtPath:outPath error:NULL];

    //格式的转换

    es.outputFileType = AVFileTypeQuickTimeMovie;

    es.outputURL = [[NSURL alloc] initFileURLWithPath:outPath];

    es.shouldOptimizeForNetworkUse=NO;

    CMTime start = CMTimeMakeWithSeconds(1.0, 600);

    CMTime duration = CMTimeMakeWithSeconds(3.0, 600);

    CMTimeRange range = CMTimeRangeMake(start, duration);

    //音频的时间范围

    es.timeRange = range;

    

    

    NSLog(@"exporting to %@",outPath);

    //异步输出完成后调用

    [es exportAsynchronouslyWithCompletionHandler:^{

        NSString *status = ;

        

        if( es.status == AVAssetExportSessionStatusCompleted ) status = @"AVAssetExportSessionStatusCompleted";

        else if( es.status == AVAssetExportSessionStatusFailed ) status = @"AVAssetExportSessionStatusFailed";

        

        

        NSLog(@"done exporting to %@ status %d = %@ (%@)",outPath,es.status, status,[es error]);

    }];

    

    

    //第二种方式读取本地到另外一个地方

    

    NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];

    NSString *audioPath = [documentPath stringByAppendingPathComponent:[NSString stringWithFormat:@"audio"]];

    

    NSURL *fileUrl = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/1141.mp3",audioPath]];

    

    

    AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:fileUrl options:nil];

    NSError *error = nil;

    

    NSArray *array=[_player.currentItem.asset tracksWithMediaType:AVMediaTypeAudio];

    

    AVAssetTrack *track=[[_player.currentItem.asset tracksWithMediaType:AVMediaTypeAudio]firstObject];

    

    NSLog(@"%@",_player.currentItem.asset);

    

    assetReader=[[AVAssetReader alloc]initWithAsset:_player.currentItem.asset error:&error];

    NSDictionary *readerOutputSettings=@{

(id)AVFormatIDKey:@(kAudioFormatLinearPCM)};

    

    //如果读取失败接下来的代码不会执行。

    

    AVAssetReaderTrackOutput *trackOutput=[[AVAssetReaderTrackOutput alloc]initWithTrack:track outputSettings:readerOutputSettings];

    [assetReader addOutput:trackOutput];

    //先判断readYES

    BOOL read= [assetReader startReading];

    

    

    NSString *userPath = [audioPath stringByAppendingPathComponent:[NSString stringWithFormat:@"/writer1.wav"]];

    NSURL *outputURL=[NSURL fileURLWithPath:userPath];

    

    assetWriter=[[AVAssetWriter alloc]initWithURL:outputURL fileType:AVFileTypeWAVE error:nil];

    AudioChannelLayout channelLayout;

    memset(&channelLayout, 0, sizeof(AudioChannelLayout));

    channelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;

    

    //lin PCM需要设置PCM一些相关的属性

    NSDictionary *writerOutputSetting=@{

(id)AVFormatIDKey:@(kAudioFormatLinearPCM),(id)AVSampleRateKey:[NSNumber numberWithFloat:44100.0],AVNumberOfChannelsKey:[NSNumber numberWithInt: 2],AVLinearPCMBitDepthKey:[NSNumber numberWithInt:16],

                                        AVLinearPCMIsNonInterleaved:[NSNumber numberWithBool:NO],

                                        AVLinearPCMIsFloatKey:[NSNumber numberWithBool:NO],

                                        AVLinearPCMIsBigEndianKey:[NSNumber numberWithBool:NO],AVChannelLayoutKey:[ NSData dataWithBytes:&channelLayout length: sizeof( AudioChannelLayout ) ]};

    

    AVAssetWriterInput *writerInput=[[AVAssetWriterInput alloc]initWithMediaType:AVMediaTypeAudio outputSettings:writerOutputSetting];

    [assetWriter addInput:writerInput];

    BOOL writer=[assetWriter startWriting];

    

    

    dispatch_queue_t dispatchQueue=dispatch_queue_create("com/tapharmonic.WriterQueue", NULL);

    

    [assetWriter startSessionAtSourceTime:kCMTimeZero];

    [writerInput requestMediaDataWhenReadyOnQueue:dispatchQueue usingBlock:^{

        

        bool complete=NO;

        while ([writerInput isReadyForMoreMediaData]&& !complete) {

            NSLog(@"%@",assetWriter.error);

            CMSampleBufferRef sampleBuffer=[trackOutput copyNextSampleBuffer];

            if(sampleBuffer){

                BOOL result=[writerInput appendSampleBuffer:sampleBuffer];

                CFRelease(sampleBuffer);

                complete=!result;

            }else{

                [writerInput markAsFinished];

                complete=YES;

            }

        }

        if(complete){

            [assetWriter finishWritingWithCompletionHandler:^{

                AVAssetWriterStatus status=assetWriter.status;

                NSLog(@"%@",assetWriter.error);

                if(status==AVAssetWriterStatusCompleted){

                    NSLog(@"AVAssetWriterStatusCompleted");

                }else{

                    NSLog(@"AVAssetWriterStatusFailed");

                }

            }];

        }

    }];

AVAssetExportSession你可以取消这个生成操作,通过给session发送 cancelExport 消息。

失败原因:

· 如果导出的文件存在,或者导出的url在沙盒之外,这个导出操作会失败。
· 来了一个电话
· 你的程序在后台运行并且其他的应用开始播放。
这种情况下,你应该通知用户export失败,并且重新export。

转载于:https://my.oschina.net/u/2483082/blog/665721

你可能感兴趣的文章
LeetCode - Search a 2D Matrix
查看>>
【转】Eclipse上安装GIT插件EGit及使用
查看>>
以交互方式使用exp/imp的演示
查看>>
Python对文件的操作(转)
查看>>
Codeforces Round #263 (Div. 2)
查看>>
软考概述
查看>>
程序猿打新总结 6月份 新股申购秘籍
查看>>
163源报错Hash Sum mismatch 解决方法
查看>>
使用ECMAscript5中的forEach函数遍历数组
查看>>
Linux之MySQL
查看>>
jekins 持续集成手记
查看>>
Android 为应用创建、删除桌面快捷方式
查看>>
Maven如何手动添加依赖的jar文件到本地Maven仓库
查看>>
Oracle安装部署,版本升级,应用补丁快速参考
查看>>
【Android】13.0 第13章 创建和访问SQLite数据库—本章示例主界面
查看>>
CentOS6.5安装Tab增强版:bash-completion
查看>>
2015华为机试——数字基root
查看>>
Java学习笔记(四):流程控制
查看>>
ios开发--第三方整理
查看>>
【JVM】JVM系列之内存模型(六)
查看>>