国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁(yè) > news >正文

怎么自己用手機(jī)做網(wǎng)站門戶網(wǎng)站軟文

怎么自己用手機(jī)做網(wǎng)站,門戶網(wǎng)站軟文,wordpress 網(wǎng)站地址,怎么在服務(wù)器里面做網(wǎng)站引言 在上一篇博客中,我們已經(jīng)介紹了創(chuàng)建視頻過(guò)渡的實(shí)現(xiàn)方案,步驟非常繁瑣,在生成AVMutableVideoCompositionInstruction和AVMutableVideoCompositionLayerInstruction的計(jì)算也十分復(fù)雜,但其實(shí)還有一個(gè)創(chuàng)建視頻組合的捷徑。不過(guò)我…

引言

在上一篇博客中,我們已經(jīng)介紹了創(chuàng)建視頻過(guò)渡的實(shí)現(xiàn)方案,步驟非常繁瑣,在生成AVMutableVideoCompositionInstruction和AVMutableVideoCompositionLayerInstruction的計(jì)算也十分復(fù)雜,但其實(shí)還有一個(gè)創(chuàng)建視頻組合的捷徑。不過(guò)我們還是需要理解上一篇博客中我們所討論的步驟,只有理解了那些步驟,才能發(fā)現(xiàn)學(xué)習(xí)這些對(duì)應(yīng)的使用變得容易許多。

創(chuàng)建組合的捷徑

AVVideoComposition定義了一個(gè)十分便捷的初始化方法init(propertiesOf asset: AVAsset),我們可以將AVCompostion作為參數(shù)來(lái)創(chuàng)建一個(gè)AVVideoComposition。該方法會(huì)為我們創(chuàng)建一個(gè)帶有如下配置的AVVideoComposition對(duì)象:

  • instructions ?屬性包含一組完整的基于組合視頻軌道(以及其中包含的片段空間布局)的組合和層指令。
  • renderSize ?屬性被設(shè)置為AVComposition對(duì)象的naturalSize,或者如果沒(méi)有設(shè)置,則使用能夠滿足組合視頻軌道中最大視頻維度的尺寸值。
  • frameDuration ?設(shè)置為組合視頻軌道中最大nominalFrameRate的值。如果所有軌道的nominalFrameRate值都為0,則frameDuration設(shè)置成默認(rèn)1/30秒(30FPS)。
  • renderScale ?始終設(shè)置為1.0。

創(chuàng)建視頻過(guò)渡

下面我們開(kāi)始著手創(chuàng)建視頻過(guò)渡,和之前的實(shí)現(xiàn)方案一樣,先創(chuàng)建一個(gè)遵循PHComposition協(xié)議名為PHTransitionComposition的類,以及遵循PHCompositionBuilder協(xié)議名為PHTransitionCompositionBuilder的類。

PHTransitionComposition負(fù)責(zé)構(gòu)建視頻的可播放和可導(dǎo)出版本。

PHTransitionCompositionBuilder負(fù)責(zé)構(gòu)建PHTransitionComposition,里面會(huì)創(chuàng)建用于視頻編輯的AVMutableComposition,AVMutableAudioMix以及AVMutableVideoComposition。

PHTransitionComposition

代碼實(shí)現(xiàn)如下:

import UIKit
import AVFoundationclass PHTransitionComposition: NSObject,PHComposition {/// 組合軌道var composition:AVMutableComposition!/// 視頻軌道var videoComposition:AVMutableVideoComposition?/// 音頻混合var audioMix:AVMutableAudioMix?init(composition: AVMutableComposition!, videoComposition: AVMutableVideoComposition?, audioMix: AVMutableAudioMix?) {self.composition = compositionself.videoComposition = videoCompositionself.audioMix = audioMix}func makePlayerItem() -> AVPlayerItem? {let playerItem = AVPlayerItem(asset: composition.copy() as! AVAsset)playerItem.videoComposition = videoCompositionplayerItem.audioMix = audioMixreturn playerItem}func makeAssetExportSession() -> AVAssetExportSession? {let exportSession = AVAssetExportSession(asset: composition.copy() as! AVAsset, presetName: AVAssetExportPresetHighestQuality)exportSession?.videoComposition = videoCompositionexportSession?.audioMix = audioMixreturn exportSession!}}

代碼較以前的類相比多了一個(gè)AVMutableVideoComposition屬性,用來(lái)實(shí)現(xiàn)視頻的過(guò)渡效果。

PHTransitionCompositionBuilder

該類中的代碼和以往一樣主要目的是構(gòu)建PHComposition,分成三個(gè)部分,添加視頻到組合軌道,添加音頻到組合軌道,添加背景音樂(lè)到組合軌道。

let defaultTransitionDuration = CMTime(value: 2, timescale: 1)class PHTransitionCompositionBuilder: NSObject,PHCompositionBuilder {/// 資源模型var timeLine:PHTimeLine!/// 組合軌道let composition = AVMutableComposition()init(timeLine: PHTimeLine!) {self.timeLine = timeLine}func buildComposition() -> PHComposition? {// 添加視頻到組合軌道addVideoCompositionTrack()// 創(chuàng)建AVVideoCompositionlet videoComposition = buildVideoComposition()// 添加音頻到組合軌道addAudioCompositionTrack()// 添加背景音樂(lè)到組合軌道let audioMix = addMusicCompositionTrack()return PHTransitionComposition(composition: composition, videoComposition: videoComposition, audioMix: audioMix)}/// 添加視頻到組合軌道func addVideoCompositionTrack() {....}/// 創(chuàng)建AVVideoCompositionfunc buildVideoComposition() -> AVMutableVideoComposition? {....}/// 添加音頻到組合軌道func addAudioCompositionTrack() {let _ = addCompositionTrack(mediaType: .audio, mediaItems: timeLine.audioItems)}/// 添加背景音樂(lè)到組合軌道func addMusicCompositionTrack() -> AVMutableAudioMix?{// 添加背景音樂(lè)var audioMix:AVMutableAudioMix? = nilif timeLine.musicItem != nil {let musicCompositionTrack =  addCompositionTrack(mediaType: .audio, mediaItems: [timeLine.musicItem!])let musicAudioMix = buildAudioMixWithTrack(track: musicCompositionTrack)audioMix = musicAudioMix}return audioMix}/// 私有方法-添加媒體資源軌道/// - Parameters:///  - mediaType: 媒體類型///  - mediaItems: 媒體媒體資源數(shù)組///  - Returns: 返回一個(gè)AVCompositionTrackprivate func addCompositionTrack(mediaType:AVMediaType,mediaItems:[PHMediaItem]?) -> AVMutableCompositionTrack? {if PHIsEmpty(array: mediaItems) {return nil}let trackID = kCMPersistentTrackID_Invalidguard let compositionTrack = composition.addMutableTrack(withMediaType: mediaType, preferredTrackID: trackID) else { return nil }//設(shè)置起始時(shí)間var cursorTime = CMTime.zeroguard let mediaItems = mediaItems else { return nil }for item in mediaItems {//這里默認(rèn)時(shí)間都是從0開(kāi)始guard let asset = item.asset else { continue }guard let assetTrack = asset.tracks(withMediaType: mediaType).first  else { continue }do {try compositionTrack.insertTimeRange(item.timeRange, of: assetTrack, at: cursorTime)} catch {print("addCompositionTrack error")}cursorTime = CMTimeAdd(cursorTime, item.timeRange.duration)}return compositionTrack}/// 創(chuàng)建音頻混合器/// - Parameters:///  - musicTrack: 音樂(lè)軌道func buildAudioMixWithTrack(track:AVMutableCompositionTrack?) -> AVMutableAudioMix? {guard let track = track else { return nil }guard let musicItem = timeLine.musicItem else { return nil }let audioMix = AVMutableAudioMix()let audioMixParam = AVMutableAudioMixInputParameters(track: track)for volumeAutomaition in musicItem.volumeAutomations {audioMixParam.setVolumeRamp(fromStartVolume: volumeAutomaition.startVolume, toEndVolume: volumeAutomaition.endVolume, timeRange: volumeAutomaition.timeRange)}audioMix.inputParameters = [audioMixParam]return audioMix}}

關(guān)于添加音頻和背景音樂(lè)以及創(chuàng)建AVAudioMix的部分,我們?cè)谇懊娴牟┛椭幸呀?jīng)進(jìn)行過(guò)介紹,在這里就不再重復(fù)解釋了,把重點(diǎn)放到添加視頻到組合軌道以及創(chuàng)建AVVideoComposition上。

下面看一下添加視頻到組合軌道的實(shí)現(xiàn):

    /// 添加視頻到組合軌道func addVideoCompositionTrack() {let compositionTrackA = self.composition.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid)let compositionTrackB = self.composition.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid)let videoTracks = [compositionTrackA,compositionTrackB]let transitionDuration = defaultTransitionDuration// 初始時(shí)間var cursorTime = CMTime.zerolet videoItems = timeLine.videoItmesfor (index,item) in videoItems.enumerated() {let trackIndex = index % 2let currentTrack = videoTracks[trackIndex]guard let asset = item.asset else { continue }guard let assetTrack = asset.tracks(withMediaType: .video).first else { continue }do {try currentTrack?.insertTimeRange(item.timeRange, of: assetTrack, at: cursorTime) } catch {print("insertTimeRange error")}// 更新cursorTimecursorTime = CMTimeAdd(cursorTime, item.timeRange.duration)cursorTime = CMTimeSubtract(cursorTime, transitionDuration)}}
  1. 首先從當(dāng)前的AVMutableComposition中創(chuàng)建兩個(gè)新的AVMutableCompositionTrack對(duì)象,兩者都是.video類型,并添加到videoTracks數(shù)組中,提供所需的A-B軌道排列。
  2. 遍歷視頻資源,將視頻資源交替插入到AB兩個(gè)軌道中。
  3. 計(jì)算cursorTime,需要考慮到減去動(dòng)畫過(guò)程的時(shí)間,因?yàn)檫@段時(shí)間兩個(gè)視頻媒體是重疊的。

創(chuàng)建AVVideoComposition的實(shí)現(xiàn)如下:

    /// 創(chuàng)建AVVideoCompositionfunc buildVideoComposition() -> AVMutableVideoComposition? {let videoComposition = AVMutableVideoComposition(propertiesOf: self.composition)videoComposition.renderSize = CGSize(width: 1920, height: 1080)/// 獲取instructionslet instructions = videoComposition.instructionsvar layerInstructionIndex = 1for instruction in instructions {guard let videoCompositionInstruction = instruction as? AVMutableVideoCompositionInstruction else { continue }let layerInstructions = videoCompositionInstruction.layerInstructions// 判斷是否有兩個(gè)layerInstructionsguard layerInstructions.count == 2 else { continue }// 創(chuàng)建過(guò)渡效果let fromeLayerInstruction = layerInstructions[1 - layerInstructionIndex] as! AVMutableVideoCompositionLayerInstructionlet toLayerInstruction = layerInstructions[layerInstructionIndex] as! AVMutableVideoCompositionLayerInstruction// 設(shè)置動(dòng)畫fromeLayerInstruction.setOpacityRamp(fromStartOpacity: 1.0, toEndOpacity: 0.0, timeRange: videoCompositionInstruction.timeRange)layerInstructionIndex = layerInstructionIndex == 1 ? 0 : 1}return videoComposition}
  1. 使用init(propertiesOf asset: AVAsset)創(chuàng)建一個(gè)新的AVVideoComposition實(shí)例,這個(gè)方法會(huì)自動(dòng)創(chuàng)建所需的組合對(duì)象和層指令。并設(shè)置renderSize、renderScale、frameDuration熟悉為相應(yīng)的值。(renderSize需要滿足組合視頻軌道中最大視頻維度的尺寸值)
  2. 遍歷videoComposition的instructions屬性,判斷videoCompositionInstruction的layerInstructions個(gè)數(shù)等于2的情況提取重疊的兩個(gè)AVMutableVideoCompositionLayerInstruction。
  3. 為兩個(gè)AVMutableVideoCompositionLayerInstruction添加一個(gè)漸變的過(guò)渡動(dòng)畫。
  4. 返回AVVideoComposition實(shí)例。

除了上面列出的最簡(jiǎn)單的漸隱過(guò)渡方式,還支持很多其它的過(guò)渡方式。

推入過(guò)渡效果:

            // 推入過(guò)渡效果let identityTransform = CGAffineTransform.identitylet videoWidth = videoComposition.renderSize.widthlet fromeTransform = CGAffineTransform(translationX: -videoWidth, y: 0)let toTransform = CGAffineTransform(translationX: videoWidth, y: 0)fromeLayerInstruction.setTransformRamp(fromStart: identityTransform, toEnd: fromeTransform, timeRange: videoCompositionInstruction.timeRange)toLayerInstruction.setTransformRamp(fromStart: toTransform, toEnd: identityTransform, timeRange: videoCompositionInstruction.timeRange)

擦除過(guò)渡效果:

            // 擦除過(guò)渡效果let width = videoComposition.renderSize.widthlet height = videoComposition.renderSize.heightlet startRect = CGRect(x: 0, y: 0, width: width, height: height)let endRect = CGRect(x: width, y: height, width: width, height: 0.0)fromeLayerInstruction.setCropRectangleRamp(fromStartCropRectangle: startRect, toEndCropRectangle: endRect, timeRange: videoCompositionInstruction.timeRange)

播放

創(chuàng)建PHTransitionCompositionBuilder實(shí)例,構(gòu)建視頻的可播放版本,進(jìn)行播放。

 func player() {guard let delegate = self.delegate else { return }let compositionBuilder = PHTransitionCompositionBuilder(timeLine: timeLine)let composition = compositionBuilder.buildComposition()let playerItem = composition?.makePlayerItem()delegate.replaceCurrentItem(playerItem: playerItem)}

結(jié)語(yǔ)

代碼中我們把工作的重點(diǎn)集中到了A-B軌道的方式交替添加視頻資源,以及構(gòu)建AVMutableVideoComposition并創(chuàng)建過(guò)渡效果上面。但事實(shí)上我們還需要注意到播放進(jìn)度的顯示,創(chuàng)建過(guò)渡后兩個(gè)視頻之間會(huì)有重疊部分,在呈現(xiàn)的時(shí)候需要減去重疊時(shí)間。

需要注意其它軌道的長(zhǎng)度需要小于視頻組合軌道的軌道長(zhǎng)度。

另外最需要注意的是AVMutableVideoComposition的renderSize熟悉,一定要使用能夠滿足組合視頻軌道中最大視頻維度的尺寸值。

http://m.aloenet.com.cn/news/42304.html

相關(guān)文章:

  • 做個(gè)類似淘寶的網(wǎng)站怎么做搜索引擎推廣的方法有哪些
  • 網(wǎng)站360自然排名要怎么做百度手機(jī)版
  • 廣州番禺網(wǎng)站建設(shè)工作室網(wǎng)站搭建
  • 網(wǎng)絡(luò)集資網(wǎng)站怎么做中國(guó)宣布取消新冠免費(fèi)治療
  • 福建龍巖疫情一共有多少例aso如何優(yōu)化
  • 建站推廣網(wǎng)站排名東莞企業(yè)網(wǎng)站排名優(yōu)化
  • 懷化同城網(wǎng)站四川游戲seo整站優(yōu)化
  • wpf 網(wǎng)站開(kāi)發(fā)百度云網(wǎng)盤資源
  • 怎么做網(wǎng)站鵝蛋生蠔指數(shù)基金定投怎么買
  • 扁平化顏色網(wǎng)站合肥網(wǎng)絡(luò)推廣公司
  • wordpress 過(guò)期時(shí)間seo是什么車
  • php做的網(wǎng)站模板下載網(wǎng)站seo優(yōu)化皆宣徐州百都網(wǎng)絡(luò)不錯(cuò)
  • opencart做網(wǎng)站視頻國(guó)外域名購(gòu)買
  • 武漢論壇網(wǎng)站有哪些怎么進(jìn)行網(wǎng)絡(luò)推廣
  • 量化交易網(wǎng)站開(kāi)發(fā)杭州網(wǎng)站優(yōu)化效果
  • 包包網(wǎng)站建設(shè)策劃書seo搜索優(yōu)化專員招聘
  • 企業(yè)網(wǎng)站管理系統(tǒng)哪個(gè)好百度開(kāi)戶代理
  • 網(wǎng)站推廣只能使用在線手段進(jìn)行。中國(guó)萬(wàn)網(wǎng)域名注冊(cè)官網(wǎng)
  • 我想在網(wǎng)站上賣食品怎么做建網(wǎng)站費(fèi)用
  • 免費(fèi)b2b網(wǎng)站要怎么做谷歌seo教程
  • 做網(wǎng)站和app多少費(fèi)用免費(fèi)網(wǎng)站推廣工具
  • p2p網(wǎng)站怎么做視頻號(hào)的鏈接在哪
  • 企業(yè)營(yíng)銷型企業(yè)網(wǎng)站建設(shè)seo如何去做優(yōu)化
  • 有道云筆記做網(wǎng)站西地那非片多少錢一盒
  • 做跨境網(wǎng)站百度搜索引擎營(yíng)銷如何實(shí)現(xiàn)
  • 青島企業(yè)做網(wǎng)站百度指數(shù)官網(wǎng)首頁(yè)
  • 網(wǎng)站企業(yè)建設(shè)方案seo外鏈要做些什么
  • 設(shè)置本機(jī)外網(wǎng)ip做網(wǎng)站營(yíng)銷軟文的范文
  • 國(guó)外做問(wèn)卷網(wǎng)站希愛(ài)力5mg效果真實(shí)經(jīng)歷
  • 學(xué)校網(wǎng)站設(shè)計(jì)流程聊城網(wǎng)站seo