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
总结:
此工程紧紧是给出了相应接口和方法,具体用户操作如选择音频淡入淡出时间,剪切从第几帧开始到第几帧结束,还需要自定义留出接口.
网友评论
歌曲剪成一条一条的,然后再去掉原唱,跟人声合成,
或者一段话,剪成一句句的,然后跟人声合成,这样的。