视频提取音频和音频裁剪

最近项目中需要从视频中提取音频,并需要根据音频时间间隔进行裁剪,所以在此记录下实现过程。

音频提取

音频提取原理是通过创建只包含原始文件的音频音轨并使用 AVAssetExportSession导出组合文件的AVMutableComposition 来完成音频提取。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/*
输出路径
self.cachePath: 获取缓存路径
*/
NSString *outPath = [self.cachePath stringByAppendingPathComponent: [NSString stringWithFormat:@"%@.m4a", name]];
// 创建组合文件
AVMutableComposition *composition = [[AVMutableComposition alloc] init];
NSURL *url = [NSURL fileURLWithPath:path];
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:url options:nil];
AVAssetTrack *track = [asset tracksWithMediaType:AVMediaTypeAudio].firstObject;
AVMutableCompositionTrack *comTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
NSError *error;
[comTrack insertTimeRange:track.timeRange ofTrack:track atTime:kCMTimeZero error:&error];
if (error) {
NSLog(@"创建失败");
}
// 创建只包含原始文件的音频音轨
AVAssetExportSession *session = [[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetPassthrough];
// 导出文件类型.m4a格式
session.outputFileType = AVFileTypeAppleM4A;
session.outputURL = [NSURL fileURLWithPath:outPath];
// 音频导出
[session exportAsynchronouslyWithCompletionHandler:^{
AVAssetExportSessionStatus status = session.status;
if(AVAssetExportSessionStatusCompleted == status) {
NSLog(@"音频导出成功");
} else {
NSLog(@"音频导出失败");
}
}];

音频裁剪

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/*
根据时间间隔裁剪音频
path: 音频路径
time: 时间间隔
*/
- (void)cutAudioWithPath:(NSString *)path intervalTime:(NSInteger)time {
// 获取音频时长
NSURL *url = [NSURL fileURLWithPath:path];
AVURLAsset*audioAsset = [AVURLAsset URLAssetWithURL:url options:nil];
CMTime totalDuration = audioAsset.duration;
CGFloat audioSeconds = CMTimeGetSeconds(totalDuration);

if (audioSeconds > time) {
NSInteger number = ceil(audioSeconds / time);
for (NSInteger idx = 0; idx < number; idx ++) {
NSInteger t = idx * time;
CMTime startTime = CMTimeMake(t, 1);;
CMTime endTime;
if (t > audioSeconds) {
endTime = CMTimeMake(audioSeconds, 1);
} else {
endTime = CMTimeMake(time, 1);
}
NSString *fileName = [NSString stringWithFormat:@"%zi.m4a", t];
NSString *outPutPath = [[self composeDir] stringByAppendingPathComponent:fileName];
NSURL *audioFileOutput = [NSURL fileURLWithPath:outPutPath];
[[NSFileManager defaultManager] removeItemAtURL:audioFileOutput error:NULL];
AVAsset *asset = [AVAsset assetWithURL:url];
AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:asset presetName:AVAssetExportPresetAppleM4A];
CMTimeRange exportTimeRange = CMTimeRangeFromTimeToTime(startTime, endTime);

exportSession.outputURL = audioFileOutput;
exportSession.outputFileType = AVFileTypeAppleM4A;
exportSession.timeRange = exportTimeRange;

[exportSession exportAsynchronouslyWithCompletionHandler:^{
if (AVAssetExportSessionStatusCompleted == exportSession.status) {
NSLog(@"导出完成: %@", outPutPath);
} else if (AVAssetExportSessionStatusFailed == exportSession.status) {
NSLog(@"导出失败: %@", exportSession.error.localizedDescription);
}
}];
}
} else {
NSLog(@"音频时长小于裁剪时间间隔");
}
}
文章作者: 落秋
文章链接: https://www.liyb.vip/2019/08/12/视频提取音频和音频裁剪/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 落秋
打赏
  • 微信
  • 支付宝

评论