删除视频背景音乐

删除视频的背景音乐其实很简单,把视频数据导入进来,然后我们的视频数据其实是有两条轨道一条是音频,另外一条是视频。由于数据的tracks(轨道包含多条音视频)
是只读的,所以在这里重新创建一个混合器,然后把数据源的视频轨道拿过来。重新生成一个媒体文件,丢弃了音频,这样就将视频的音频给删除掉了。

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
/** 删除视频的音频 */
static func remove_video_audio(_ url: URL, finish:@escaping(URL?)->Void) {
/* 导出的视频路径 */
let exportURL = URL(fileURLWithPath: get_audio_name("."+url.pathExtension))
/** 删除重复的文件 */
try? FileManager.default.removeItem(at: exportURL)
/* 获取视频数据源 */
let videoAsset = AVURLAsset(url: url)

// 创建媒体组合器
let mixComposition = AVMutableComposition()
/** 时长 */
let timeRange = CMTimeRangeMake(start: CMTime.zero, duration: videoAsset.duration)
/** 视频轨道 */
guard let videoTrack = videoAsset.tracks(withMediaType: .video).last else {
finish(nil)
return
}

/** 混合器 */
let videoCompositionTrack = mixComposition.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid)
try? videoCompositionTrack?.insertTimeRange(timeRange, of: videoTrack, at: CMTime.zero)

//合成输出
let assetExport = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPresetHighestQuality)
assetExport?.outputURL = exportURL
/** 设置视频导出格式 */
var fileType: AVFileType = .mov
if url.pathExtension == "mp4" {
fileType = .mp4
}
assetExport?.outputFileType = fileType
assetExport?.shouldOptimizeForNetworkUse = true
assetExport?.exportAsynchronously(completionHandler: {
if assetExport?.status == AVAssetExportSession.Status.completed {
finish(exportURL)
} else {
finish(nil)
print("error = \(assetExport?.error?.localizedDescription ?? "删除视频的音频失败")")
}
})
}

添加视频背景音乐

给视频添加背景音乐,创建一个混合器把传进来的音频和视频添加进去,再按照格式导出。由于是新创建的所以原有的音频会被丢弃。

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
48
/** 给视频添加背景音乐 */
static func video_add_backgroundAudio(_ url: URL, audioURL: URL, finish:@escaping (URL?)->Void) {
/** 导出视频路径 */
let exportURL = URL(fileURLWithPath: get_audio_name("."+url.pathExtension))
/** 删除文件 */
try? FileManager.default.removeItem(at: exportURL)
/** 获取数据源 */
let videoAsset = AVURLAsset(url: url)
let audioAsset = AVURLAsset(url: audioURL)
/** 时长 */
let timeRange = CMTimeRangeMake(start: CMTime.zero, duration: videoAsset.duration)
/** 音频视频轨道 */
guard let videoTrack = videoAsset.tracks(withMediaType: .video).last else {
finish(nil)
return
}
guard let audioTrack = audioAsset.tracks(withMediaType: .audio).last else {
finish(nil)
return
}
/** 混合器 */
let mixComposition = AVMutableComposition()
/** 添加视频轨道 */
let videoCompositionTrack = mixComposition.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid)
try? videoCompositionTrack?.insertTimeRange(timeRange, of: videoTrack, at: CMTime.zero)
/** 添加音频轨道 */
let audioCompositionTrack = mixComposition.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid)
try? audioCompositionTrack?.insertTimeRange(timeRange, of: audioTrack, at: CMTime.zero)

/** 合成输出 */
let assetExport = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPresetHighestQuality)
assetExport?.outputURL = exportURL
/** 设置视频导出格式 */
var fileType: AVFileType = .mov
if url.pathExtension == "mp4" {
fileType = .mp4
}
assetExport?.outputFileType = fileType
assetExport?.shouldOptimizeForNetworkUse = true
assetExport?.exportAsynchronously(completionHandler: {
if assetExport?.status == AVAssetExportSession.Status.completed {
finish(exportURL)
} else {
finish(nil)
print("error = \(assetExport?.error?.localizedDescription ?? "删除视频的音频失败")")
}
})
}

相关文章
评论
分享
  • AAC音频转WAV

    将aac编码格式的音频转为lpcm编码的音频,转出来的音频会比原来大个10倍左右.1234567891011121314151617181920212223242526272829303132333435363738394041424...

    AAC音频转WAV
  • Message Filtter Extension 短信过滤

    手机最近老是收到各种垃圾短信,于是想要自己写一个app来过滤垃圾短信,找到了Message Filtter Extension 1.首先创建一个空的工程,然后创建好了之后添加一个target。1选中工程->Editor-&g...

    Message Filtter Extension 短信过滤
  • Shell删除所有苹果证书

    123456789101112131415161718#!/bin/bashexpired=$(security find-identity)if [ -z "$expired" ] #-z判断字符串长度是否为0 为0返回tru...

    Shell删除所有苹果证书
  • Swift语言国际化

    第一步在工程设置里面添加对应国际化的语言 第二步添加Localizble.strings 第三步选择Localizble.strings文件,然后选择Localize…选择需要的语言,选择完了之后你就会看见刚才创建的Localizbl...

    Swift语言国际化
  • Docker Nginx 静态资源部署

    1. 查看docker仓库中的nginx命令1docker search nginx 2.为选定需要pull到系统重的官方Nginx镜像1docker pull nginx 这个过程需要时间,需要耐心等待一下。看到这个图就是成功了。 ...

    Docker Nginx 静态资源部署
  • Nginx vue打包部署

    最近在弄vue的项目,完了需要打包部署到服务器,然后之前也没有弄过自己在这边一边查资料一边琢磨怎么弄。幸运的是花了一天半的时间还搞定了。 1.在conf.d文件下添加一个新的配置文件,12345678910111213141516...

    Nginx vue打包部署
  • SCP文件上传下载

    从服务器获取文件1scp -p 8080 root@192.168.1.1:/usr/temp/file.txt /Desktop/ 上传文件到服务器1scp -p 8080 /Desktop/uploadfile root@192....

    SCP文件上传下载
  • 音频剪切、合成、淡入淡出

    音频剪切1.音频剪切比较简单传入音频文件和剪切的时间段就可以了12345678910111213141516171819202122232425/** 初始化输出文件路径 */ NSString *url = "音频源文件路径"...

    音频剪切、合成、淡入淡出
  • swift 做一个答题的功能

    实现的效果是:1.点击答案,判断正确,如果选择的答案错误显示出正确的答案。然后可以浏览上一题的信息。2.可以查看上一题的答题情况。看下效果图吧 思路:1.看看题的模型吧,我这里是用一个数组来装的一个类,然后点击下一题的时候数组索引+...

    swift 做一个答题的功能
  • iOS原生调用ReatNative

    有一个RN的项目其中一个即时通讯的模块需要用原生来写所以这里面就涉及到iOS原生和RN的交互。 iOS调用RN1.创建一个交互通信的类。1234#import <React/RCTEventEmitter.h>#imp...

    iOS原生调用ReatNative