一.音视频编辑 - 功能概述

引言

编辑其实就是选择,编排最佳镜头提供连贯的内容。AV Foundation给出了一些API来创建非线性、无损的编辑工具,术语”非线行“的意思是可以自由组合、分开、修建、覆盖和以任何顺序重排媒体片段直到满足我们的期望。最好的一点是这些编辑操作都是无损的,即最初的源媒体资源不会被破坏,可以无约束地进行编辑。

概述

本篇博客就来介绍一下音视频编辑所涉及的功能和简单实现。

媒体组合

媒体组合就是将多个视频资源组合起来成一个视频资源,再配上合适的音乐。

AV Foundation 有关资源组合的功能源于AVAsset的子类AVComposition。一个组合就是将其他几种媒体资源组合成一个自定义的临时排列,再将这个临时排列视为一个可呈现或处理的独立媒体项目。就比如AVAsset对象,组合相当于包含了一个或多个给定类型的媒体轨道的容器。AVComposition中的轨道都是AVAssetTrack的子类AVCompositionTrack。一个组合轨道本身由一个或多个媒体片段组成,由AVCompositionTrackSegment类定义。

简单的实现如下:

1.假设我们有三个已知的媒体资源,两个视频资源一个音频资源。

        let goldenGateAsset = AVURLAsset(url: URL(string: "1")!, options: nil)
        let teaGardenAsset = AVURLAsset(url: URL(string: "2")!, options: nil)
        let soundTrackAsset = AVURLAsset(url: URL(string: "3")!, options: nil)

2.创建AVComposition的可变子类,以及获取视频音频AVMutableCompositionTrack。

        let composition = AVMutableComposition()
        var videoTrack = composition.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid)!
        var audioTrack = composition.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid)

3.获取视频资源的track并添加到视频的AVMutableCompositionTrack中。

        var cursorTime = CMTime.zero
        let videoDuration = CMTime(value: 5, timescale: 1)
        let videoTimeRange = CMTimeRange(start: cursorTime, duration: videoDuration)
        let goldenGateAssetTrack = goldenGateAsset.tracks(withMediaType: .video).first!
        do {
            try videoTrack.insertTimeRange(videoTimeRange, of: goldenGateAssetTrack, at: cursorTime)
        } catch {
            print("Error inserting time range: \(error)")
        }
         
        cursorTime = CMTimeAdd(cursorTime, videoDuration)
        let teaGardenAssetTrack = teaGardenAsset.tracks(withMediaType: .video).first!
        do {
            try videoTrack.insertTimeRange(videoTimeRange, of: teaGardenAssetTrack, at: cursorTime)
        } catch {
            print("Error inserting time range: \(error)")
        }

4.获取音频资源的track并添加到音频的AVMutableCompositionTrack中。

        cursorTime = CMTime.zero
        let audioDuration = composition.duration
        let audioTimeRange = CMTimeRangeMake(start: cursorTime, duration: audioDuration)
        let soundTrackAssetTrack = soundTrackAsset.tracks(withMediaType: .audio).first!
        do {
            try audioTrack?.insertTimeRange(audioTimeRange, of: soundTrackAssetTrack, at: cursorTime)
        } catch {
            print("Error inserting time range: \(error)")
        }

混合音频

当有多个音频轨道混合在一起的时候,我们就会需要让有些声音突出,有些声音减小,比如背景音乐和独白,如果背景音乐的声音完全盖过了独白,那显然是不太符合用户期望的。

AV Foundation框架提供了AVAudioMix类,它用来在组合的音频轨道中进行自定义音频的处理。AVAudioMix所具有的音频处理方法是由它的输入参数集定义的,它的参数是AVAudioMixInputParameters类型的对象。AVAudioMixInputParameters的实例关联组合中的单独音频轨道,并在添加到音频混合时定义基于轨道的处理方法。AVAudioMix和其相关联的AVAudioMixInputParameters集合都是不可变对象,意味着它们适用于为AVPlayerItem和AVAssetExportSession之类的客户端提供相关数据,不过它们不能操作其状态。当我们需要创建一个自定义音频混合时,需要改用它们在AVMutableAudioMix和AVMutableAudioMixInputParameters中的可变子类。

简单实现如下:

1.假设已有一个音频轨道AVCompositionTrack。

        let soundTrackAsset = AVURLAsset(url: URL(string: "3")!, options: nil)
        let track:AVCompositionTrack = soundTrackAsset.tracks(withMediaType: .audio).first! as! AVCompositionTrack

2.定义音量变化的时间。

        let twoSeconds = CMTimeMake(value: 2, timescale: 1)
        let foureSeconds = CMTimeMake(value: 4, timescale: 1)
        let sevenSeconds = CMTimeMake(value: 7, timescale: 1)

3.创建AVMutableAudioMixInputParameters,并设置音量。

        let parameters = AVMutableAudioMixInputParameters(track: track)
        
        parameters.setVolume(0.5, at: CMTime.zero)
        
        let range = CMTimeRangeFromTimeToTime(start: twoSeconds, end: foureSeconds)
        
        parameters.setVolumeRamp(fromStartVolume: 0.5, toEndVolume: 0.8, timeRange: range)
        
        parameters.setVolume(0.3, at: sevenSeconds)

4.创建AVMutableAudioMix,将AVMutableAudioMixInputParameters传递给AVMutableAudioMix。

        let audioMix = AVMutableAudioMix()
        audioMix.inputParameters = [parameters]

添加视频过度效果

大部分视频编辑应用程序的一个重要功能就是能够创建动态视频过渡效果。AV Foundation对于这一功能的支持具有很高的可靠性,不过同时也被认为是学习媒体编辑API中最具有挑战性的一个领域。

需要涉及到几个陌生的类:

AVVideoComposition:框架的视频过渡类API中最核心的类是AVVideoComposition。这个类对两个或多个视频轨道组合在一起的方法给出了一个总体描述。

AVVideoCompositionInstruction:这个对象所提供的最关键的一段数据是组合对象时间轴内的时间范围信息,这一时间范围是在某一组合形式出现时的时间范围。

AVVideoCompositionLayerInstruction:AVVideoCompositionLayerInstruction用于定义对给定视频轨道应用的模糊,变形和裁剪效果。

要想实现视频的过度效果需要通过以下几个步骤:

1.部署视频布局。

要在剪辑间添加过渡,首先需要将两个轨道间的视频片段重新部署。我们已经知道如何将多个音频轨道组合在一起,那么视频的情况也是一样的。大多数情况下两个轨道就足够了,不过为了满足一些特殊需求而加入更多的轨道也是可以的,要注意同时添加过多的轨道会对性能产生负面影响。

2.定义重叠区域。

要在两个片段中应用视频过渡,需要根据期望的过渡持续时长来确定片段的重叠情况。

3.计算通过和过度的时间范围。

 AVVideoComposition由一组AVVideoCompositionInstruction对象组成。其中最重要的数据是时间范围,它用来表示某种出现的组合方式持续的时长。在开始创建AVVideoCompositionInstruction实例前,首先需要为组合对象计算一系列时间范围。

4.创建组合和层指令。

下一步是创建AVVideoCompositionInstruction和AVVideoCompositionLayerInstruction实例,提供视频组合方式所执行的指令。

5.创建和配置AVVideoComposition。

最困难的工作已经完成了,剩下的就是创建和配置一个AVVideoCompostion实例。

添加动画图层内容

视频中添加的动画使用的是我们非常熟悉的 Core Animation框架。

使用Core Animation为视频应用程序创建叠加效果的方法同使用它在iOS或OS X平台创建实时动画效果的方法几乎一样。最大的区别在于运行动画的时间模型,当创建实时动画时,CAAnimation实例从系统主机时钟获取执行时间。

视频动画需要基于“影片时间”来操作,开始的时间应该是影片开始的时间直到影片持续时间结束。另外主机时间时一直向前推荐,从不会停止,而影片时间可以停止、暂停回退或快进。因为动画需要紧密地与视频时间轴绑定,所以需要使用不同的场景时间模式。

AV Foundation提供了一个专门CALayer子类AVSynchronizedLayer,用于与给定的AVPlayerItem实例同步时间。这个图层本身不展示任何内容,仅用来与图层子树协同时间。这样所有在基础关系中附属于该图层的动画都可以从激活的AVPlayerItem实例中获取相应的执行时间。

结语

在本篇博客中,我们探讨了iOS平台上音视频编辑的一些基础概念和技术。通过媒体组合,混合音频,添加过渡效果和动画图层等技术,我们可以为用户提供更加丰富和生动的音视频体验。音视频编辑在移动应用开发中扮演着重要角色,它为开发者提供了无限的创作可能性,使得我们可以创造出更加引人入胜的应用程序。希望本篇博客能够为你提供一些有用的信息,并激发你对音视频编辑技术的进一步探索和应用。期待在未来的技术探索中,我们能够共同创造出更加出色的应用和体验!

相关推荐

  1. .视频编辑 - 功能概述

    2024-03-29 13:30:05       45 阅读
  2. 视频主要概念

    2024-03-29 13:30:05       33 阅读
  3. 视频实战--视频编码

    2024-03-29 13:30:05       38 阅读
  4. 视频技术应用方向概述

    2024-03-29 13:30:05       28 阅读
  5. 视频编码基础知识

    2024-03-29 13:30:05       66 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-29 13:30:05       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-29 13:30:05       100 阅读
  3. 在Django里面运行非项目文件

    2024-03-29 13:30:05       82 阅读
  4. Python语言-面向对象

    2024-03-29 13:30:05       91 阅读

热门阅读

  1. LVS(Layout versus schematic)比的是什么?

    2024-03-29 13:30:05       40 阅读
  2. 网络安全的攻防战争

    2024-03-29 13:30:05       34 阅读
  3. Mysql中不同库的两个表怎么做数据同步

    2024-03-29 13:30:05       39 阅读
  4. WINDOWS增加NTP服务器功能

    2024-03-29 13:30:05       42 阅读
  5. 如何将模型实例化

    2024-03-29 13:30:05       37 阅读
  6. vue3页面路由缓存的一种方法

    2024-03-29 13:30:05       38 阅读
  7. 一段typescript+html实现的table增删改

    2024-03-29 13:30:05       40 阅读
  8. tp8用切换数据库的方式实现城市分站

    2024-03-29 13:30:05       38 阅读
  9. 《青少年成长管理2024》 009 “成长需要成本”

    2024-03-29 13:30:05       37 阅读
  10. mockito-02-spring aop 与 mockito 冲突及解决方案

    2024-03-29 13:30:05       39 阅读
  11. 【MySQL】mysql数据库小功能整理,持续更新~

    2024-03-29 13:30:05       40 阅读