iOS 开发之-音频剪切

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

总结:

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,504评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,434评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,089评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,378评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,472评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,506评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,519评论 3 413
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,292评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,738评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,022评论 2 329
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,194评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,873评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,536评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,162评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,413评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,075评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,080评论 2 352

推荐阅读更多精彩内容

  • 《ilua》速成开发手册3.0 官方用户交流:iApp开发交流(1) 239547050iApp开发交流(2) 1...
    叶染柒丶阅读 10,631评论 0 11
  • “您好,我是这里的财务L,请问可以和您一起用餐吗?” “啊!当然可以,欢迎呢,我们是同行耶!” “真的吗?哈哈!那...
    夏威一一阅读 197评论 0 1
  • 你是一个善良,懂事、开朗、喜欢唱歌、跳舞的女孩,进入初中这一周以来,我发现你有了很大的变化,比如主动早起锻炼身体,...
    玺祥阅读 315评论 0 0
  • 非常简单,只要在Podfile中移除相应的库,保存后再次pod install即可。
    NapoleonY阅读 245评论 0 0
  • 今天背单词时看到了EX,因为忙碌而麻木的心又疼到失眠。 遇到一个自己喜欢的人不容易, 遇到一个各种嫌弃自己但仍然爱...
    浮生aureate阅读 551评论 1 2