- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在构建一个应用程序,它结合了几个视频,将它们合并为一个并在视频中放置了自定义音轨。这一切都完美无缺。现在我想淡出我的音频。另一方面,这是行不通的,我不知道为什么。这是我的代码:
let duration = composition.duration
let durationInSeconds = CMTimeGetSeconds(duration) * 10
let composition = AVMutableComposition()
let item = AVPlayerItem(asset: composition)
let params = AVMutableAudioMixInputParameters(track: composition.tracks.first! as AVAssetTrack)
let lastSecond = CMTimeRangeMake(CMTimeMakeWithSeconds(durationInSeconds-10, 10), CMTimeMakeWithSeconds(1, 1))
params.setVolumeRamp(fromStartVolume: 1, toEndVolume: 0, timeRange: lastSecond)
let mix = AVMutableAudioMix()
mix.inputParameters = [params]
item.audioMix = mix
// Put the track under the video
do {
try audioTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, current), of: backgroundAudio.tracks(withMediaType: AVMediaTypeAudio)[0], at: kCMTimeZero)
} catch _ {
print("Failed to load Audio track")
}
guard let exporter = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetHighestQuality) else { return }
exporter.audioMix = mix
exporter.outputURL = URL(fileURLWithPath: finalVideoPath)
exporter.outputFileType = AVFileTypeMPEG4
exporter.shouldOptimizeForNetworkUse = true
在这个代码块之后,它继续到另一个方法,在该方法中呈现视频本身。有人可以向我解释为什么这不起作用以及如何解决这个问题吗?
提前致谢!
最佳答案
这是添加视频和音频 url 并设置两者音量的代码。您的结果视频将具有淡入和淡出效果。
func mergeVideoAndMusicWithVolume(videoURL: NSURL, audioURL: NSURL, startAudioTime: Float64, volumeVideo: Float, volumeAudio: Float, complete: ((NSURL?)) -> Void) -> Void {
//The goal is merging a video and a music from iPod library, and set it a volume
//Get the path of App Document Directory
let dirPaths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
let docsDir = dirPaths[0] as String
//Create Asset from record and music
let assetVideo: AVURLAsset = AVURLAsset(URL: videoURL)
let assetMusic: AVURLAsset = AVURLAsset(URL: audioURL)
let composition: AVMutableComposition = AVMutableComposition()
let compositionVideo : AVMutableCompositionTrack = composition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: CMPersistentTrackID())
let compositionAudioVideo: AVMutableCompositionTrack = composition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: CMPersistentTrackID())
let compositionAudioMusic: AVMutableCompositionTrack = composition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: CMPersistentTrackID())
//Add video to the final record
do {
try compositionVideo.insertTimeRange(CMTimeRangeMake(kCMTimeZero, assetVideo.duration), ofTrack:assetVideo.tracksWithMediaType(AVMediaTypeVideo)[0], atTime: kCMTimeZero)
} catch _ {
}
//Extract audio from the video and the music
let audioMix: AVMutableAudioMix = AVMutableAudioMix()
var audioMixParam: [AVMutableAudioMixInputParameters] = []
let assetVideoTrack: AVAssetTrack = assetVideo.tracksWithMediaType(AVMediaTypeAudio)[0]
let assetMusicTrack: AVAssetTrack = assetMusic.tracksWithMediaType(AVMediaTypeAudio)[0]
let videoParam: AVMutableAudioMixInputParameters = AVMutableAudioMixInputParameters(track: assetVideoTrack)
videoParam.trackID = compositionAudioVideo.trackID
let musicParam: AVMutableAudioMixInputParameters = AVMutableAudioMixInputParameters(track: assetMusicTrack)
musicParam.trackID = compositionAudioMusic.trackID
//Set final volume of the audio record and the music
videoParam.setVolume(volumeVideo, atTime: kCMTimeZero)
musicParam.setVolume(volumeAudio, atTime: kCMTimeZero)
//Add setting
audioMixParam.append(musicParam)
audioMixParam.append(videoParam)
//Add audio on final record
//First: the audio of the record and Second: the music
do {
try compositionAudioVideo.insertTimeRange(CMTimeRangeMake(kCMTimeZero, assetVideo.duration), ofTrack: assetVideoTrack, atTime: kCMTimeZero)
} catch _ {
assertionFailure()
}
do {
try compositionAudioMusic.insertTimeRange(CMTimeRangeMake(CMTimeMake(Int64(startAudioTime * 10000), 10000), assetVideo.duration), ofTrack: assetMusicTrack, atTime: kCMTimeZero)
} catch _ {
assertionFailure()
}
//Add parameter
audioMix.inputParameters = audioMixParam
//Remove the previous temp video if exist
let filemgr = NSFileManager.defaultManager()
do {
if filemgr.fileExistsAtPath("\(docsDir)"){
try filemgr.removeItemAtPath("\(docsDir)/movie-merge-music.mp4")
} else {
}
} catch _ {
}
//Exporte the final record’
let completeMovie = "\(docsDir)/\(randomString(5)).mp4"
let completeMovieUrl = NSURL(fileURLWithPath: completeMovie)
let exporter: AVAssetExportSession = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetHighestQuality)!
exporter.outputURL = completeMovieUrl
exporter.outputFileType = AVFileTypeMPEG4
exporter.audioMix = audioMix
exporter.exportAsynchronouslyWithCompletionHandler({
switch exporter.status {
case AVAssetExportSessionStatus.Completed:
print("success with output url \(completeMovieUrl)")
case AVAssetExportSessionStatus.Failed:
print("failed \(String(exporter.error))")
case AVAssetExportSessionStatus.Cancelled:
print("cancelled \(String(exporter.error))")
default:
print("complete")
}
})
}
关于ios - AVAssetExportSession,带 AudioMix 的 AVMutableComposition 淡出不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46669673/
首先,我不确定这是否是报告此问题的正确位置,但在任何地方都找不到任何信息或任何类型的文档。 几天(也许几周)前,Android Vitals 开始提醒我们 Google Play 仪表板中的“不良行为
我想在我的应用程序中使用音频混合器,它接收来自不同来源的音频,并应在扬声器中一起播放它们。 我的最终应用程序应该执行类似以下命令的操作: gst-launch-1.0 audiomixer name=
我正在开发将多个视频与背景音轨结合在一起的应用程序。它还需要为不同的视频设置不同的音频级别。 以下是AssetItem类和AssetManager类的代码 // AssetItem Class cl
问题:尝试创建一个应用到 AVPlayerItem 的 Mix,但它在点击 setVolumeRampFromStartVolume 时因 ECX_BAD_ACCESS 而崩溃: 代码: AVMuta
我正在构建一个应用程序,它结合了几个视频,将它们合并为一个并在视频中放置了自定义音轨。这一切都完美无缺。现在我想淡出我的音频。另一方面,这是行不通的,我不知道为什么。这是我的代码: let durat
我是一名优秀的程序员,十分优秀!