在我的应用程序中,我需要合并音频和视频,然后我需要在Mediaplayer中播放音频文件.如何在IOS中合并音频和视频.是否有任何源代码.请给我一些想法
提前致谢
我创建了下面的合并方法(加入、联合,我不确定哪个词是正确的,我想从 2 个或更多音频中制作 1 个音频,而不是一个接一个地播放,而是一次播放每个音频)。作为输入,我有多个 .wav 格式的音频文件,并且我希望输出有 1 个 .wav 格式。
func merge(audioUrls: [NSURL], resultName : String = "result") {
let resultNameWithExtension = resultName + ".wav"
//Create AVMutableComposition Object.This object will hold our multiple AVMutableCompositionTrack.
let composition = AVMutableComposition()
//create new file to receive data
//let documentDirectoryURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first!
let outputFilePath = NSTemporaryDirectory().stringByAppendingPathComponent(resultNameWithExtension)
let fileDestinationUrl = NSURL(fileURLWithPath: outputFilePath)
print(fileDestinationUrl)
StorageManager.sharedInstance.deleteFileAtPath(NSTemporaryDirectory().stringByAppendingPathComponent(resultNameWithExtension))
var avAssets: [AVURLAsset] = []
var assetTracks: [AVAssetTrack] = []
var timeRanges: [CMTimeRange] = []
for audioUrl in …Run Code Online (Sandbox Code Playgroud) 我正在尝试在 macOS 上使用 Swift、AVFoundation 和 AVKit 将多个电影的片段一起编辑到一个剪辑中。下面的 Swift 代码是我正在尝试做的事情的一个很好的例子:
\n\nimport AVFoundation\nimport AVKit\n\nlet source1 = AVAsset(url: URL(string: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4")!)\nlet source2 = AVAsset(url: URL(string: "http://techslides.com/demos/sample-videos/small.mp4")!)\n\nlet comp = AVMutableComposition()\n\ncomp.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid)\ncomp.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid)\n\nfunc cmtime(_ i: Double) -> CMTime {\n return CMTime(seconds: i, preferredTimescale: 600)\n}\n\nfunc insertSecond(into: AVMutableComposition, from: AVAsset, start: CMTime, at: CMTime) throws {\n let videoTrack = into.tracks(withMediaType: .video).first!\n let audioTrack = into.tracks(withMediaType: .audio).first!\n try videoTrack.insertTimeRange(\n CMTimeRange(start: start , duration: cmtime(1.0)),\n of: from.tracks(withMediaType: .video).first!,\n at: at\n )\n try audioTrack.insertTimeRange(\n CMTimeRange(start: start, …Run Code Online (Sandbox Code Playgroud) 我正在开发一款将多个视频剪辑合并为一个最终视频的应用程序。我希望用户能够根据需要将各个剪辑静音(因此,只有最终合并视频的部分内容会被静音)。我将 AVAssets 包装在一个名为“Video”的类中,该类具有“shouldMute”属性。
我的问题是,当我将其中一个 AVAssetTrack 的音量设置为零时,它在最终视频的其余部分中保持静音。这是我的代码:
var completeDuration : CMTime = CMTimeMake(0, 1)
var insertTime = kCMTimeZero
var layerInstructions = [AVVideoCompositionLayerInstruction]()
let mixComposition = AVMutableComposition()
let audioMix = AVMutableAudioMix()
let videoTrack =
mixComposition.addMutableTrack(withMediaType: AVMediaType.video,
preferredTrackID: kCMPersistentTrackID_Invalid)
let audioTrack = mixComposition.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid)
// iterate through video assets and merge together
for (i, video) in clips.enumerated() {
let videoAsset = video.asset
var clipDuration = videoAsset.duration
do {
if video == clips.first {
insertTime = kCMTimeZero
} else {
insertTime = …Run Code Online (Sandbox Code Playgroud) 我正在开发一个项目,其中我试图使用AVMutableComposition. 我的视频文件,当保存到我的相机胶卷时,都完全符合预期。他们的 URL 是有效的,但我最终导出的产品只显示第一个视频,而不显示第二个合并的视频。这是我正在使用的代码:
// Setup video asset
let videoAsset: AVAsset = AVAsset( url: clip1 )
// Setup composition
let composition = AVMutableComposition()
// Get video track
let vtrack = videoAsset.tracks(withMediaType: AVMediaType.video)
// Setup the first video track as asset track
let videoTrack: AVAssetTrack = vtrack[0]
// Setup the video timerange
let vid_timerange = CMTimeRangeMake(kCMTimeZero, videoAsset.duration)
// Setup the composition video track
let compositionvideoTrack:AVMutableCompositionTrack = composition.addMutableTrack(withMediaType: AVMediaType.video, preferredTrackID: kCMPersistentTrackID_Invalid)!
// Insert expected time range
do {
try compositionvideoTrack.insertTimeRange(vid_timerange, …Run Code Online (Sandbox Code Playgroud) 我的应用程序从 URL 获取视频,并允许您向其中添加文本等。当视频没有任何音频开始时,它似乎崩溃了,似乎无法弄清楚这一点。
这是我在制作视频时所拥有的:
let asset = AVAsset(url: URL(string: self.videoURL)!)
let mixComposition = AVMutableComposition()
let videoTrack = mixComposition.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid)
try! videoTrack?.insertTimeRange(CMTimeRangeMake(start: .zero, duration: asset.duration), of: asset.tracks(withMediaType: .video)[0], at: CMTime.zero)
let audioTrack = mixComposition.addMutableTrack(withMediaType: .audio, preferredTrackID: Int32(kCMPersistentTrackID_Invalid))
do {
try audioTrack!.insertTimeRange(CMTimeRangeMake(start: .zero, duration: asset.duration), of: asset.tracks(withMediaType: .audio)[0], at: CMTime.zero)
} catch {
print("error")
}
Run Code Online (Sandbox Code Playgroud)
它继续insertTimeRange说indexPath超出范围。
[__NSArray0 objectAtIndex:]: index 0 beyond bounds for empty NSArray
Run Code Online (Sandbox Code Playgroud) 我有两个音轨,我就像这样相互结合:
AVMutableComposition *composition = [[AVMutableComposition alloc] init];
AVMutableCompositionTrack *compositionAudioTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
[compositionAudioTrack setPreferredVolume:1.0];
AVAsset *avAsset = [AVURLAsset URLAssetWithURL:originalContentURL options:nil];
AVAssetTrack *clipAudioTrack = [[avAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
[compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, avAsset.duration) ofTrack:clipAudioTrack atTime:kCMTimeZero error:nil];
AVMutableCompositionTrack *compositionAudioTrack1 = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
[compositionAudioTrack1 setPreferredVolume:0.01];
NSString *soundOne1 =[[NSBundle mainBundle]pathForResource:@"jingle1" ofType:@"m4a"];
NSURL *url1 = [NSURL fileURLWithPath:soundOne1];
AVAsset *avAsset1 = [AVURLAsset URLAssetWithURL:url1 options:nil];
AVAssetTrack *clipAudioTrack1 = [[avAsset1 tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
[compositionAudioTrack1 insertTimeRange:CMTimeRangeMake(kCMTimeZero, avAsset.duration) ofTrack:clipAudioTrack1 atTime:kCMTimeZero error:nil];
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,第一个AVAsset是第二个轨道的基本长度,这意味着如果我有一个很长的第二个轨道,它将被切割,这正是我想要的方式.
但是,我需要能够循环第二个轨道,这样如果第一个轨道太长,第二个轨道就会继续运行.我后来不得不将生成的曲目保存在光盘上,这也是一个重要因素.
经过一项研究,我发现在iOS中实际循环轨道没有方便的方法.其中一种方法是AVMutableComposition反复插入第二首曲目,但这对我来说听起来很奇怪.基于该主题的任何想法都将非常有用.
我有一个[AVAsset]数组,我正在尝试将所有这些资产组合成一个资产,以便我可以无缝播放视频(我尝试使用AVQueuePlayer,但不能无缝播放资产).
下面是我到目前为止所做的,但当我尝试播放最终乐曲时,它只播放第一首曲目,即使它表明它具有所有曲目且总持续时间等于所有曲目.
我是否错过了一个步骤,即使看起来所有曲目都在合成中?如果AVPlayerItem有多个轨道,也许我需要以不同的方式处理AVPlayer?
let playerLayer: AVPlayerLayer = AVPlayerLayer()
lazy var videoPlayer: AVPlayer = AVPlayer()
var videoClips = [AVAsset]()
let videoComposition = AVMutableComposition()
var playerItem: AVPlayerItem!
var lastTime: CMTime = kCMTimeZero
for clipIndex in videoClips {
let videoCompositionTrack = videoComposition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: Int32(kCMPersistentTrackID_Invalid))
do {
try videoCompositionTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, clipIndex.duration),
ofTrack: clipIndex.tracksWithMediaType(AVMediaTypeVideo)[0] ,
atTime: lastTime)
lastTime = CMTimeAdd(lastTime, clipIndex.duration)
} catch {
print("Failed to insert track")
}
}
print("VideoComposition Tracks: \(videoComposition.tracks.count)") // Shows multiple tracks
playerItem = AVPlayerItem(asset: videoComposition)
print("PlayerItem Duration: \(playerItem.duration.seconds)") // Shows …Run Code Online (Sandbox Code Playgroud) 类AVMutableCompositionTrack的insertTimeRange:ofTrack:atTime:error:在iPhone(但不是模拟器)上返回NO,并且错误“操作无法完成”。错误消息没有帮助,我很想找出错误的原因,更不用说解决方法了。任何帮助,将不胜感激。
在下面的示例代码中,我要做的就是尝试将音频剪辑添加到AVMutableCompositionTrack。这是代码中发生的事情:
AVMutableComposition和AVMutableCompositionTrack对象是在init中创建的。
调用class方法addPhrase:atTime:将音频剪辑添加到合成音轨。
实际插入的函数是addAudioClip:atTime:。
辅助函数audioClipWithName:ofType将请求的音频文件加载到AVAssetTrack中。
-> NSLOG输出:
insertTimeRange atTime = 0.0范围=(0.0,2.1)compositionTrack = ----------错误!错误域= AVFoundationErrorDomain代码= -11800“操作无法完成” UserInfo = {NSLocalizedDescription =操作无法完成,NSUnderlyingError = 0x16fc1c90 {Error Domain = NSOSStatusErrorDomain代码= -12780“(null)”},NSLocalizedFailureReason = An发生未知错误(-12780)}
->样本代码:
@interface MyAudioPlayer()
@property (strong, nonatomic) AVMutableComposition *composition;
@property (strong, nonatomic) AVMutableCompositionTrack *compositionTrack;
@end
@implementation MyAudioPlayer
- (id) init
{
self = [super init];
if (self != nil) {
self.composition = [AVMutableComposition composition];
self.compositionTrack = [self.composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
}
return self;
}
// Add the phrase into compositionAudioTrack at the given …Run Code Online (Sandbox Code Playgroud) 我正在从 UIImage 数组制作视频。我成功地做到了并且所有图像都显示在视频中。我正在使用 AVAssetExportSession 导出视频,该视频也可以正常工作,除非我使用 AVAssetExportSession videoComposition 属性时,视频仅显示第一张图像。这是我的代码:
func mergeAudioVideoFiles(videoUrl:NSURL, audioUrl:NSURL)->NSURL
{
let mixComposition : AVMutableComposition = AVMutableComposition()
var mutableCompositionVideoTrack : [AVMutableCompositionTrack] = []
var mutableCompositionAudioTrack : [AVMutableCompositionTrack] = []
let totalVideoCompositionInstruction : AVMutableVideoCompositionInstruction = AVMutableVideoCompositionInstruction()
//start merge
let aVideoAsset : AVAsset = AVAsset(URL: videoUrl)
let aAudioAsset : AVAsset = AVAsset(URL: audioUrl)
mutableCompositionVideoTrack.append(mixComposition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid))
mutableCompositionAudioTrack.append( mixComposition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid))
let aVideoAssetTrack : AVAssetTrack = aVideoAsset.tracksWithMediaType(AVMediaTypeVideo)[0]
let aAudioAssetTrack : AVAssetTrack = aAudioAsset.tracksWithMediaType(AVMediaTypeAudio)[0]
do{
try mutableCompositionVideoTrack[0].insertTimeRange(CMTimeRangeMake(kCMTimeZero, aVideoAssetTrack.timeRange.duration), ofTrack: aVideoAssetTrack, atTime: kCMTimeZero)
try …Run Code Online (Sandbox Code Playgroud) 我正在编写一个使用AVFoundation和CMTime的应用程序.我已经记录了CMTime使用创建的实例的值CMTimeMake().此值似乎四舍五入到最接近的整数.我需要一个CMTime具有精确值的实例,而不需要舍入.
我在CMTime参考文献中看到了舍入常量:
enum {
kCMTimeRoundingMethod_RoundHalfAwayFromZero = 1,
kCMTimeRoundingMethod_RoundTowardZero = 2,
kCMTimeRoundingMethod_RoundAwayFromZero = 3,
kCMTimeRoundingMethod_QuickTime = 4,
kCMTimeRoundingMethod_RoundTowardPositiveInfinity = 5,
kCMTimeRoundingMethod_RoundTowardNegativeInfinity = 6,
kCMTimeRoundingMethod_Default = kCMTimeRoundingMethod_RoundHalfAwayFromZero
};
Run Code Online (Sandbox Code Playgroud)
没有任何关于如何控制这些策略应用于CMTime实例的示例?或者,如果这不是正确的方法,我如何从CMTime实例中提取精确值?
编辑:
我找到并测试过了CMTIME_HAS_BEEN_ROUNDED().我将我的CMTime实例传递给了这个函数并返回No(表示该值尚未舍入).那为什么我会失去精确度呢?
我正在创建一个带有一系列图像和一个音频文件的电影,并将创建的电影保存到照片库,在模拟器中我正在使用我的图像和音频文件阵列获得正确的电影但是在设备中运行时我没有得到我的结果电影相反,我得到了我添加的视频(我在我的代码中使用的OutPut.mov)来编写我的输出文件(混合音频和图像文件数组).
这是我的代码将我的混合音频和图像数组文件保存到照片库:
AVMutableComposition* mixComposition = [AVMutableComposition composition];
NSString* audio_inputFilePath = [[NSBundle mainBundle] pathForResource:@"Ruler" ofType:@"caf"];
NSURL* audio_inputFileUrl = [NSURL fileURLWithPath:audio_inputFilePath];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
NSString *video_inputFilePath = [documentsDirectory stringByAppendingPathComponent:@"videoOutput1234videoOutput1234.mp4"];
NSLog(@"output url %@",video_inputFilePath);
NSURL* video_inputFileUrl = [NSURL fileURLWithPath:video_inputFilePath];
NSString* outputFilePath = [[NSBundle mainBundle] pathForResource:@"OutPut" ofType:@"mov"];
NSURL* outputFileUrl = [NSURL fileURLWithPath:outputFilePath];
if ([[NSFileManager defaultManager] fileExistsAtPath:outputFilePath])
[[NSFileManager defaultManager] removeItemAtPath:outputFilePath error:nil];
if ([[NSFileManager defaultManager] fileExistsAtPath:outputFilePath])
[[NSFileManager defaultManager] removeItemAtPath:outputFilePath error:nil];
CMTime nextClipStartTime …Run Code Online (Sandbox Code Playgroud) 我正在构建能够录制视频并使用 和 在录制的视频上添加动画叠加的 iOS 应用AVFoundation程序CAAnimation。所有子功能都工作正常,但播放动画时视频背景的结尾是黑色的。它没有渲染我选择的背景视频。我曾经AVAssetWriter录制过视频,并且在相机胶卷上播放得很好。但如果我使用这个录制的视频添加叠加,视频末尾的背景是黑色的。有趣的是,如果我通过本机 iOS 相机应用程序录制视频并使用它添加叠加层,它就可以完美工作。我已经检查过这个问题,但对我没有用。黑色视频 CAAnimation 和 AVFoundation AVAssetExportSession
任何帮助将不胜感激。谢谢
avfoundation caanimation ios avassetwriter avmutablecomposition
ios ×9
swift ×7
avasset ×6
avfoundation ×6
iphone ×3
objective-c ×2
audio ×1
avplayer ×1
caanimation ×1
cocoa-touch ×1
core-audio ×1
core-media ×1
ffmpeg ×1
ios4 ×1
mp4 ×1