iOS 音视频合成, AVMutableComposition来合成音视频


音视频主要是利用AVFoundation框架下的AVMutableComposition来合成音视频.

在AVMutableComposition中传入两个数据流,一个是音频一个是视频,之后调用合成方法就可以了

上代码

storyBoard中拖入一个button,一个imageView


这里写图片描述

为了效果好可以将IamgeView的背景色调为黑色

然后在ViewController中添加以下代码

#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
#import "MBProgressHUD+MJ.h"
@interface ViewController ()
/** 用于播放 */
@property (weak, nonatomic) IBOutlet UIImageView *imageView;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

}

- (IBAction)mergeAction:(UIButton *)sender {
    [self merge];
}
// 混合音乐
- (void)merge{
    // mbp提示框
    [MBProgressHUD showMessage:@"正在处理中"];
    // 路径
    NSString *documents = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
    // 声音来源
    NSURL *audioInputUrl = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"五环之歌" ofType:@"mp3"]];
    // 视频来源
    NSURL *videoInputUrl = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"myPlayer" ofType:@"mp4"]];

    // 最终合成输出路径
    NSString *outPutFilePath = [documents stringByAppendingPathComponent:@"merge.mp4"];
    // 添加合成路径
    NSURL *outputFileUrl = [NSURL fileURLWithPath:outPutFilePath];
    // 时间起点
    CMTime nextClistartTime = kCMTimeZero;
    // 创建可变的音视频组合
    AVMutableComposition *comosition = [AVMutableComposition composition];


    // 视频采集
    AVURLAsset *videoAsset = [[AVURLAsset alloc] initWithURL:videoInputUrl options:nil];
    // 视频时间范围
    CMTimeRange videoTimeRange = CMTimeRangeMake(kCMTimeZero, videoAsset.duration);
    // 视频通道 枚举 kCMPersistentTrackID_Invalid = 0
    AVMutableCompositionTrack *videoTrack = [comosition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
    // 视频采集通道
    AVAssetTrack *videoAssetTrack = [[videoAsset tracksWithMediaType:AVMediaTypeVideo] firstObject];
    //  把采集轨道数据加入到可变轨道之中
    [videoTrack insertTimeRange:videoTimeRange ofTrack:videoAssetTrack atTime:nextClistartTime error:nil];



    // 声音采集
    AVURLAsset *audioAsset = [[AVURLAsset alloc] initWithURL:audioInputUrl options:nil];
    // 因为视频短这里就直接用视频长度了,如果自动化需要自己写判断
    CMTimeRange audioTimeRange = videoTimeRange;
    // 音频通道
    AVMutableCompositionTrack *audioTrack = [comosition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
    // 音频采集通道
    AVAssetTrack *audioAssetTrack = [[audioAsset tracksWithMediaType:AVMediaTypeAudio] firstObject];
    // 加入合成轨道之中
    [audioTrack insertTimeRange:audioTimeRange ofTrack:audioAssetTrack atTime:nextClistartTime error:nil];

    // 创建一个输出
    AVAssetExportSession *assetExport = [[AVAssetExportSession alloc] initWithAsset:comosition presetName:AVAssetExportPresetMediumQuality];
    // 输出类型
    assetExport.outputFileType = AVFileTypeQuickTimeMovie;
    // 输出地址
    assetExport.outputURL = outputFileUrl;
    // 优化
    assetExport.shouldOptimizeForNetworkUse = YES;
    // 合成完毕
    [assetExport exportAsynchronouslyWithCompletionHandler:^{
        // 回到主线程
        dispatch_async(dispatch_get_main_queue(), ^{
            // 调用播放方法
            [self playWithUrl:outputFileUrl];
        });
    }];
}

/** 播放方法 */
- (void)playWithUrl:(NSURL *)url{
    // 传入地址
    AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:url];
    // 播放器
    AVPlayer *player = [AVPlayer playerWithPlayerItem:playerItem];
    // 播放器layer
    AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];
    playerLayer.frame = self.imageView.frame;
    // 视频填充模式
    playerLayer.videoGravity = AVLayerVideoGravityResizeAspect;
    // 添加到imageview的layer上
    [self.imageView.layer addSublayer:playerLayer];
    // 隐藏提示框 开始播放
    [MBProgressHUD hideHUD];
    [MBProgressHUD showSuccess:@"合成完成"];
    // 播放
    [player play];
}

MBP是一个第三方提示类,如果不关心这个功能可以删除这三行代码和头文件

// mbp提示框
    [MBProgressHUD showMessage:@"正在处理中"];
// 隐藏提示框 开始播放
    [MBProgressHUD hideHUD];
    [MBProgressHUD showSuccess:@"合成完成"];

效果图

因为是gif..请自己yy出Uber视频配上五环之歌(我感觉还挺配的)


这里写图片描述

GitHub:https://github.com/Lafree317/MergeVideoAndMusic




  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
iOS中使用FFmpeg进行音视频同步可以通过以下步骤来实现: 1. 下载FFmpeg库 你可以通过CocoaPods等方式下载FFmpeg库。在Podfile文件中添加以下代码: ```ruby pod 'FFmpeg' ``` 下载完后运行`pod install`指令安装FFmpeg库。 2. 音视频解码 使用FFmpeg库进行音视频解码。对于音频和视频,你需要分别解码它们的数据。解码后的音频和视频数据通常存储在`AVFrame`结构体中。 3. 音视频同步 音视频同步的主要难点在于如何将两个不同的时钟进行同步。通常情况下,你需要使用音频时钟来同步视频帧,因为音频时钟是相对稳定的,而视频时钟可能会因为帧率不稳定等原因而不稳定。 具体实现方法可以采用以下步骤: - 获取音频播放时间戳(PTS) - 获取视频帧显示时间戳(PTS) - 计算音视频时间差 - 根据时间差进行音视频同步 其中,音频播放时间戳可以通过audio queue的回调函数获取,视频帧显示时间戳可以通过解码后的AVFrame结构体中的`pts`字段获取,时间差可以通过两个时间戳的差值计算得到。 4. 音视频渲染 在完成音视频同步后,你需要使用OpenGL ES或者Core Graphics等技术来渲染视频帧,同时使用Audio Queue或者OpenAL等技术来播放音频帧。 需要注意的是,iOS中使用FFmpeg进行音视频同步是一个比较复杂的过程,需要一定的技术基础和经验。同时,由于FFmpeg库的复杂性和特性,可能会涉及到一些版权和法律问题。因此,建议在使用前仔细查阅相关文档和法律条款,以免出现不必要的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值