UWP 手繪視頻創作工具技術分享系列 - 手繪視頻導出

来源:http://www.cnblogs.com/shaomeng/archive/2017/10/23/7680210.html
-Advertisement-
Play Games

手繪視頻最終的生成物是視頻文件,前面幾篇主要講的是手繪視頻的創作部分,今天講一下手繪視頻的導出問題。主要以 UWP 為例,另外會介紹一些 Web 端遇到的問題和解決方法。 如上所述,手繪視頻在創作後,最終會導出為視頻文件,如 MP4,WMV 等,我們目前的選擇是 MP4,整個導出大致分為幾個步驟: ...


手繪視頻最終的生成物是視頻文件,前面幾篇主要講的是手繪視頻的創作部分,今天講一下手繪視頻的導出問題。主要以 UWP 為例,另外會介紹一些 Web 端遇到的問題和解決方法。

如上所述,手繪視頻在創作後,最終會導出為視頻文件,如 MP4,WMV 等,我們目前的選擇是 MP4,整個導出大致分為幾個步驟:

1. 後臺渲染手繪視頻

後臺渲染我們藉助的還是 Win2D,前面幾篇介紹過,創作繪製過程也是藉助 Win2D 來完成動態渲染的。把需要渲染的元素和指定的時間等屬性傳遞給 Win2D,其他的由 Win2D 去完成,這裡不多作介紹。

2. 按幀率定製截取圖片

這個步驟的實現方式較多,我們使用的是 CanvasBitmap.CreateFromBytes 和 MediaClip.CreateFromSurface 的方式截圖,並把每部分的視頻片段文件保存下來,看一段示例代碼:

var img = CanvasBitmap.CreateFromBytes(device, screen.GetPixelBytes(), (int)screen.SizeInPixels.Width, (int)screen.SizeInPixels.Height, screen.Format);
var clip = MediaClip.CreateFromSurface(img, span);
layerTmp.Overlays.Add(CreateMediaOverlay(clip, size, s - start));
var composition = new MediaComposition();
composition.Clips.Add(MediaClip.CreateFromSurface(bkScreen, TimeSpan.FromMilliseconds(s - start)));
composition.OverlayLayers.Add(layerTmp);
var mediaPartFile = await ApplicationData.Current.TemporaryFolder.CreateFileAsync($"part_{mediafileList.Count}.mp4", CreationCollisionOption.ReplaceExisting);
await composition.RenderToFileAsync(mediaPartFile, MediaTrimmingPreference.Fast, MediaEncodingProfile.CreateMp4(quality));
mediafileList.Add(mediaPartFile);

3. 圖片序列生成視頻

這一步驟,普遍來講都是通過 FFMpeg 來實現,FFMpeg 在 C# 語言方面也有很多封裝版本可用。不過我們在 UWP 中並沒有使用 FFMpeg,一方面代碼庫體積較大,另一方面我們有 MediaComposition 和 MediaClip 可用。

我們使用前面步驟保存下來的視頻片段,使用 MediaComposition.RenderToFileAsync 方法保存到視頻文件 ××.mp4 中:

foreach (var mediaPartFile in mediafileList)
{
    var mediaPartClip = await MediaClip.CreateFromFileAsync(mediaPartFile);
    bkComposition.Clips.Add(mediaPartClip);
}
var saveOperation = bkComposition.RenderToFileAsync(file, MediaTrimmingPreference.Fast,
MediaEncodingProfile.CreateMp4(quality));

4. 處理插入視頻的音軌

這一步驟操作相對簡單,因為 MediaOverlay 對聲音的支持很方便,我們只需要把插入的視頻,按照設定的開始時間和結束時間做裁剪,然後做好指定的旋轉等變換,接下來設置 MediaOvelay.AudioEnabled = true; 就可以了,如果需要對視頻靜音,就設置為 false。

var overlay = CreateMediaOverlay(overlayClip, size, effect.StartAt);
overlay.AudioEnabled = videoGlygh.IsEnableAudio;
layer.Overlays.Add(overlay);
bkComposition.OverlayLayers.Add(layer);

5. 處理視頻背景音樂

處理背景音樂也是使用 MediaComposition 的 BackgroundAudioTracks,通過音頻文件來創建 BackgroundAudioTrack。它是一個 iList 類型,也就是說我們可以加入多個音軌。看一下簡單的示例代碼:

StorageFile music = await StorageFile.GetFileFromApplicationUriAsync(new Uri(DrawOption.Instance.DefaultMusic.url));
var backgroundTrack = await BackgroundAudioTrack.CreateFromFileAsync(music);
bkComposition.BackgroundAudioTracks.Add(backgroundTrack);

這裡需要處理一些特殊情況,比如手繪視頻中允許音頻文件迴圈播放,這時我們需要對音頻文件做一下拼接,簡單的根據視頻時間和音頻時間做一下手動拼接:

int i = 1;
 while (DrawOption.Instance.MusicLoop && duration.TotalMilliseconds * i < total)
{
    var track = await BackgroundAudioTrack.CreateFromFileAsync(music);
    track.Delay = TimeSpan.FromMilliseconds(i * duration.TotalMilliseconds);
    bkComposition.BackgroundAudioTracks.Add(track);
    ++i;
}

 

到這裡我們就完成了在 UWP 中導出手繪視頻的工作,而導出時間一般和視頻解析度,渲染元素的複雜度有很大關聯,目前 720P 視頻的導出時間大概是手繪視頻時長的 2 倍左右。當視頻很長,比如超過 10 分鐘時,導出時間會變得比較長,之前我們也 fix 過一個 bug,就是圖片大量保存到本地時,本地磁碟 IO 變成了瓶頸,磁碟占用量也很高,後面針對這個 bug 做了修改,把本地保存文件改為記憶體中持有,做好 GC 工作。

這樣一來,視頻導出的時間消耗就可以接受了,同時我們還有 Web 端平臺,它同樣也具備手繪視頻創作和導出的功能,它的導出功能是在伺服器端完成的,伺服器是 Linux,它並沒有 UWP 這麼幸運,它的導出工作運行起來比較緩慢,基本會在視頻長度的 5- 10倍左右,流程如下:

這裡影響導出時間的主要是 PhantomJS 的截圖,它的性能不好,每幀圖片截圖的時間很久,拖慢了整體速度。而目前我們想到了,除了使用 C++ 重新寫一下截圖的功能,沒有其他好的辦法,而即使重寫,效率提升也不會太大。

基於這些問題,我們想到了另一個解決辦法,在用戶本地,使用瀏覽器插件或本地應用程式,來完成轉換並同步到伺服器。下麵簡單說說我們目前嘗試的幾種方案:

1. 傳統的錄屏方案

在我們考慮把 Web 端視頻生成轉移到本地的第一時間,就想到了這個方案。實現方面相對於用戶直接使用一個 3rdParty 的錄屏軟體,不同點就在於我們可以獲取用戶選擇了什麼音頻作為背景音樂,我們可以把它上傳到伺服器端,展示在‘我的作品’列表裡。流程如下圖:

 這種方式實現相對簡單,基本就是 FFMpeg 的使用,但是弊端也很明顯。因為是錄屏,所以錄製過程中,用戶的瀏覽器不能移動、不能最小化、也不能暫停,而且必須預覽完整的一遍,不可控性非常多,所以很快就被否決了。

2. Web 端結合本地程式方案

這個方案需要 Web 端和本地程式各自做一些事情,簡單來說就是本地程式在本機啟動一個服務,Web 端按照幀率在後臺渲染的 Canvas 里截取圖片傳給本地程式,本地程式生成視頻,合成音軌,上傳到伺服器,流程如圖:

本地程式是一個後臺服務,沒有界面,不需要用戶配合,瀏覽器只要不關閉就可以完成,用戶不需要進行預覽,這些就是這個方案的優點。目前這個方案正在開發中,開發完成後,我們會就這個方案詳細做分享,還是一種很腦洞的實現方式。

 

到這裡我們就講解完畢了,UWP 的視頻導出,Web 端視頻導出的問題,以及目前我們想到的解決方案,如果大家有更好的辦法,歡迎反饋給我們,感謝!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 第1章 數據實時同步介紹 1.1 什麼是實時同步:如何實現實時同步 A. 要利用監控服務(inotify),監控同步數據伺服器目錄中信息的變化 B. 發現目錄中數據產生變化,就利用rsync服務推送到備份伺服器上 1.2 實現實時同步的方法 inotify+rsync 方式實現數據同步 sersyn ...
  • 雖然通過了Service解決了Pod重建後 IP動態變化(服務發現)、負載均衡問題 ,但使用Service還是要需要知道CLUSTER IP,而通過NDS可以解決該問題;在Kubernetes集群中可 通過DNS進行Service服務名與IP進行映射 ,從而需要知道Service名稱就可以訪問該服務 ...
  • 由於實驗室的項目需要實現在CephFS之上建立NFS之上,所以記錄一下NFS伺服器的安裝與配置流程。 1.NFS服務的簡介: NFS 是 N etwork F ile S ystem 的縮寫,是Sun公司於1984開發的一種分散式文件系統協議。它的核心功能就是可以通過網路,讓不同的客戶端,可以彼此訪 ...
  • 1、安裝 ROS Kinetic僅支持Wily(Ubuntu 15.10)、Xenial( Ubuntu16.04)和Jessie(Debian 8)的debian軟體包。 1.1 配置Ubuntu 庫 配置你的Ubuntu庫允許“restricted”、“universe”和“multiverse ...
  • 最近項目中需要用到Python調用oracle實現讀寫操作,踩過很多坑,歷盡艱辛終於實現了。性能怎樣先不說,有方法後面再調優嘛。現在把代碼和註意點記錄一下。 1. 所需Python工具庫 cx_Oracle,pandas,可以使用通過控制台使用pip進行安裝(電腦中已經安裝) 2. 實現查詢操作 # ...
  • 1》Ansible 1>ansible簡介 ansible是新出現的自動化運維工具,基於Python開發,集合了眾多運維工具(puppet、cfengine、chef、func、fabric)的優點,實現了批量系統配置、批量程式部 署、批量運行命令等功能。ansible是基於模塊工作的,本身沒有批量 ...
  • 1.玩crond必須以下任務開啟 [root@wen ~]# chkconfig --list crond crond 0:off 1:off 2:on 3:on 4:on 5:on 6:off [root@wen ~]# ps -ef |grep crond|grep -v grep root 1 ...
  • 今天遇到這麼一個問題,打開VS啟動調試,始終報錯,如下圖: 我重啟VS,甚至重啟電腦都不得行,那個進程號還在變化,就在網上查找資料,各式各樣的解決方案,這裡我記錄我成功的方案。 打開項目文件地址,在解決方案根目錄下找到.vs文件: 刪除.vs 然後重啟vs即可。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...