美文网首页OC开发
iOS 开发之-音频剪切

iOS 开发之-音频剪切

作者: 我叫巴图图 | 来源:发表于2016-03-14 21:08 被阅读2513次

    mian.m 以及appdelegage就不说了,主要说说C控制 。

    主要功能如下:
    选择歌曲:
    剪切歌曲:
    2个消息
    1、C工作
    2、MODEL剪切工作

    VTMViewController.h

    #import <UIKit/UIKit.h>
    02
    //基库,一系列的Class(类)来建立和管理iPhone OS应用程序的用户界面接口、应用程序对象、事件控制、绘图模型、窗口、视图和用于控制触摸屏等的接口
    03
    #import <AVFoundation/AVFoundation.h> //音频处理
    04
    #import <MediaPlayer/MediaPlayer.h> //媒体库
    05
    @interface VTMViewController : UIViewController <MPMediaPickerControllerDelegate> {
    06
        //媒体选择控制器的委托
    07
            MPMediaItem *song; //歌曲 媒体类型
    08
            UILabel *songLabel; //歌曲 文本类型
    09
            UILabel *artistLabel; //艺术家 文本类型
    10
            UILabel *sizeLabel; //大小  文本类型
    11
            UIImageView *coverArtView; //转化艺术家 图片类型
    12
            UIProgressView *conversionProgress; //进度指示器类型
    13
             
    14
    }
    15
    //多线成,retain<>IBOutlet引用计数加2还是1,IB控制关联
    16
    @property (nonatomic, retain) IBOutlet UILabel *songLabel;  //监控song lable文本
    17
    @property (nonatomic, retain) IBOutlet UILabel *artistLabel; //监控artist lable文本
    18
    @property (nonatomic, retain) IBOutlet UILabel *sizeLabel; //监控0btyes lable文本
    19
    @property (nonatomic, retain) IBOutlet UIImageView *coverArtView; //监控UIImageView块
    20
    @property (nonatomic, retain) IBOutlet UIProgressView *conversionProgress;
    21
    //监控进度条块
    22
     
    23
    //IBAction->IB控件的相应动作关联
    24
    -(IBAction) chooseSongTapped: (id) sender; //选择歌曲 通用对象类型参数
    25
    -(IBAction) convertTapped: (id) sender;//改变 通用对象类型参数
    26
    - (BOOL)exportAsset:(AVAsset *)avAsset toFilePath:(NSString *)filePath;
    27
      //字符串类型
    28
    @end
    
    

    VTMViewController.m

    #import "VTMViewController.h"
    002
    #import <AudioToolbox/AudioToolbox.h> //音频处理
    003
     
    004
     
    005
     
    006
    #define EXPORT_NAME @"exported.caf"
    007
    @implementation VTMViewController
    008
     
    009
    //合成器
    010
    @synthesize songLabel;
    011
    @synthesize artistLabel;
    012
    @synthesize sizeLabel;
    013
    @synthesize coverArtView;
    014
    @synthesize conversionProgress;
    015
     
    016
    #pragma mark init/dealloc
    017
    //释放内存
    018
    - (void)dealloc {
    019
        [super dealloc];
    020
    }
    021
     
    022
    #pragma mark vc lifecycle
    023
    //视图已完全过渡到屏幕上时调用
    024
    -(void) viewDidAppear:(BOOL)animated {
    025
            [super viewDidAppear:animated];
    026
    }
    027
     
    028
    #pragma mark event handlers
    029
    /*
    030
     选择歌曲, 监听载入Button按钮
    031
     从mediaPlayer.framework里的MPMusicPlayerController类来播放ipod库中自带的音乐
    032
     */
    033
    -(IBAction) chooseSongTapped: (id) sender {
    034
            MPMediaPickerController *pickerController =        [[MPMediaPickerController alloc] //初始化
    035
             initWithMediaTypes: MPMediaTypeMusic];
    036
            pickerController.prompt = @"Choose song to export";//提示
    037
            pickerController.allowsPickingMultipleItems = NO; //是否可以多选
    038
            pickerController.delegate = self; //委托给自己
    039
            [self presentModalViewController:pickerController animated:YES]; //播放选中的歌曲
    040
            [pickerController release]; //引用计数减一
    041
             
    042
    }
    043
     
    044
    /*
    045
     剪切歌曲,监听剪切按钮
    046
     大概流程
    047
     1、获取歌曲路径,初始化音频文件
    048
     2、返回音频文件数据,测试是否接收器是否正常
    049
     3、设置新的音频路径,
    050
     4、开始剪切
    051
     */
    052
    -(IBAction) convertTapped: (id) sender {
    053
            // set up an AVAssetReader to read from the iPod Library
    054
            NSURL *assetURL = [song valueForProperty:MPMediaItemPropertyAssetURL]; //获取歌曲地址
    055
            AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL:assetURL options:nil]; //初始化音频媒体文件
    056
             
    057
            NSError *assetError = nil; //错误标识
    058
            AVAssetReader *assetReader = [[AVAssetReader assetReaderWithAsset:songAsset
    059
                                                                                                                                    error:&assetError]
    060
                                             
    061
                            retain];//指定媒体文件返回数据,返回失败抛出一个错误
    062
        /*
    063
          如果有错误,则格式化输出错误后,跳出
    064
         */
    065
            if (assetError) {
    066
                    NSLog (@"error: %@", assetError);
    067
                    return;
    068
            }
    069
             
    070
            AVAssetReaderOutput *assetReaderOutput = [[AVAssetReaderAudioMixOutput
    071
                                                                                               assetReaderAudioMixOutputWithAudioTracks:songAsset.tracks
    072
                                                                                               audioSettings: nil]
    073
                                                                                              retain]; //读取指定文件的音频轨道混音
    074
        /*
    075
         判断是否能够接收器能够正常接收,如果不能,格式化输出提示,跳出
    076
         */
    077
            if (! [assetReader canAddOutput: assetReaderOutput]) {
    078
                    NSLog (@"can't add reader output... die!");
    079
                    return;
    080
            }
    081
            [assetReader addOutput: assetReaderOutput];//输出音乐
    082
             
    083
        NSArray *dirs = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);//获取应用程序私有目录
    084
        /*
    085
         [[[dirs objectAtIndex:0] stringByAppendingPathComponent:EXPORT_NAME]];  简洁版
    086
         */
    087
        NSString *documentsDirectoryPath = [dirs objectAtIndex:0]; //返回第一个对象
    088
            NSString *exportPath = [[documentsDirectoryPath stringByAppendingPathComponent:EXPORT_NAME] retain]; //剪切文件名(如果没有就创建,有就打开)
    089
     
    090
         
    091
        /*
    092
         检查目录是否存在,存在则删除
    093
         */
    094
            if ([[NSFileManager defaultManager] fileExistsAtPath:exportPath]) {
    095
                    [[NSFileManager defaultManager] removeItemAtPath:exportPath error:nil];
    096
            }
    097
         
    098
            NSURL *exportURL = [NSURL fileURLWithPath:exportPath];//返回文件路径
    099
            AVAssetWriter *assetWriter = [[AVAssetWriter assetWriterWithURL:exportURL
    100
                                                                                                                       fileType:AVFileTypeCoreAudioFormat
    101
                                                                                                                              error:&assetError]
    102
                                                                      retain];//开始录制
    103
        /*
    104
         如果有错误,则格式化输出错误后,跳出
    105
         */
    106
            if (assetError) {
    107
                    NSLog (@"error: %@", assetError);
    108
    return;
    109
            }
    110
     
    111
                                     [self exportAsset:songAsset toFilePath:exportPath];
    112
                             
    113
                                     [exportPath release];//引用计数减一
    114
             
    115
    }
    116
     
    117
     
    118
     
    119
     
    120
    /*
    121
     剪切开始工作
    122
     大概流程
    123
    1、获得视频总时长,处理时间,数组格式返回音频数据
    124
    2、创建导出会话
    125
    3、设计导出时间范围,淡出时间范围
    126
    4、设计新音频配置数据,文件路径,类型等
    127
    5、开始剪切
    128
     */
    129
    - (BOOL)exportAsset:(AVAsset *)avAsset toFilePath:(NSString *)filePath {
    130
             
    131
        // we need the audio asset to be at least 50 seconds long for this snippet
    132
        CMTime assetTime = [avAsset duration];//获取视频总时长,单位秒
    133
        Float64 duration = CMTimeGetSeconds(assetTime); //返回float64格式
    134
        if (duration < 20.0) return NO; //小于20秒跳出
    135
             
    136
        // get the first audio track
    137
        NSArray *tracks = [avAsset tracksWithMediaType:AVMediaTypeAudio]; //返回该音频文件数据的数组
    138
        if ([tracks count] == 0) return NO; //如果没有数据,跳出
    139
             
    140
        AVAssetTrack *track = [tracks objectAtIndex:0];//获取第一个对象
    141
             
    142
        // create the export session
    143
        // no need for a retain here, the session will be retained by the
    144
        // completion handler since it is referenced there
    145
        //创建导出会话
    146
        AVAssetExportSession *exportSession = [AVAssetExportSession
    147
                                               exportSessionWithAsset:avAsset
    148
                                               presetName:AVAssetExportPresetAppleM4A];
    149
        if (nil == exportSession) return NO;//创建失败,则跳出
    150
             
    151
        // create trim time range - 20 seconds starting from 30 seconds into the asset
    152
        CMTime startTime = CMTimeMake(30, 1);//CMTimeMake(第几帧, 帧率) 30
    153
        CMTime stopTime = CMTimeMake(50, 1);//CMTimeMake(第几帧, 帧率)50
    154
        CMTimeRange exportTimeRange = CMTimeRangeFromTimeToTime(startTime, stopTime);//导出时间范围
    155
             
    156
        // create fade in time range - 10 seconds starting at the beginning of trimmed asset
    157
        CMTime startFadeInTime = startTime;//30
    158
        CMTime endFadeInTime = CMTimeMake(40, 1);//40
    159
        CMTimeRange fadeInTimeRange = CMTimeRangeFromTimeToTime(startFadeInTime, //淡入时间范围
    160
                                                                endFadeInTime);
    161
             
    162
        // setup audio mix
    163
        AVMutableAudioMix *exportAudioMix = [AVMutableAudioMix audioMix];//实例新的可变音频混音
    164
        AVMutableAudioMixInputParameters *exportAudioMixInputParameters =
    165
            [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:track]; //给track 返回一个可变的输入参数对象
    166
             
    167
        [exportAudioMixInputParameters setVolumeRampFromStartVolume:0.0 toEndVolume:1.0
    168
                                                                                                              timeRange:fadeInTimeRange]; //设置指定时间范围内导出
    169
        exportAudioMix.inputParameters = [NSArray
    170
                                          arrayWithObject:exportAudioMixInputParameters]; //返回导出数据转化为数组
    171
             
    172
        // configure export session  output with all our parameters 新的配置信息
    173
        exportSession.outputURL = [NSURL fileURLWithPath:filePath]; // output path 新文件路径
    174
        exportSession.outputFileType = AVFileTypeAppleM4A; // output file type 新文件类型
    175
        exportSession.timeRange = exportTimeRange; // trim time range //剪切时间
    176
        exportSession.audioMix = exportAudioMix; // fade in audio mix //新的混音音频
    177
             
    178
        // perform the export  开始真正工作
    179
        [exportSession exportAsynchronouslyWithCompletionHandler:^{ //block
    180
                     
    181
            if (AVAssetExportSessionStatusCompleted == exportSession.status) { //如果信号提示已经完成
    182
                NSLog(@"AVAssetExportSessionStatusCompleted"); //格式化输出成功提示
    183
            } else if (AVAssetExportSessionStatusFailed == exportSession.status) {  //如果信号提示已经完成
    184
     
    185
                // a failure may happen because of an event out of your control
    186
                // for example, an interruption like a phone call comming in
    187
                // make sure and handle this case appropriately
    188
                NSLog(@"AVAssetExportSessionStatusFailed"); //格式化输出失败提示
    189
            } else {
    190
                NSLog(@"Export Session Status: %d", exportSession.status);  //格式化输出信号状态
    191
            }
    192
        }];
    193
             
    194
        return YES;
    195
    }
    196
    @end
    
    

    总结:

    此工程紧紧是给出了相应接口和方法,具体用户操作如选择音频淡入淡出时间,剪切从第几帧开始到第几帧结束,还需要自定义留出接口.

    相关文章

      网友评论

      • 5d2bd3822d54:请问如果要多次剪切的话有什么方法或者SDK吗?
        歌曲剪成一条一条的,然后再去掉原唱,跟人声合成,
        或者一段话,剪成一句句的,然后跟人声合成,这样的。
      • puppySweet:AssetWriter是干嘛的 看了代码好像没有用啊

      本文标题:iOS 开发之-音频剪切

      本文链接:https://www.haomeiwen.com/subject/dgiflttx.html