IT知识库 购物 网址 游戏 小说 歌词 快照 开发 股票 美女 新闻 笑话 | 汉字 软件 日历 阅读 下载 图书馆 编程 China
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
vbs/VBScript DOS/BAT hta htc python perl 游戏相关 VBA 远程脚本 ColdFusion ruby专题 autoit seraphzone PowerShell linux shell Lua Golang Erlang 其它教程 CSS/HTML/Xhtml html5 CSS XML/XSLT Dreamweaver教程 经验交流 开发者乐园 Android开发资料
站长资讯 .NET新手 ASP.NET C# WinForm Silverlight WCF CLR WPF XNA VisualStudio ASP.NET-MVC .NET控件开发 EntityFramework WinRT-Metro Java C++ PHP Delphi Python Ruby C语言 Erlang Go Swift Scala R语言 Verilog 其它语言 架构设计 面向对象 设计模式 领域驱动 Html-Css JavaScript jQuery HTML5 SharePoint GIS技术 SAP OracleERP DynamicsCRM K2 BPM 信息安全 企业信息 Android开发 iOS开发 WindowsPhone WindowsMobile 其他手机 敏捷开发 项目管理 软件工程 SQLServer Oracle MySQL NoSQL 其它数据库 Windows7 WindowsServer Linux
  IT知识库 -> WinRT-Metro -> UWP 手绘视频创作工具技术分享系列 -> 正文阅读

[WinRT-Metro]UWP 手绘视频创作工具技术分享系列

UWP 手绘视频创作工具技术分享系列 手绘视频最终的生成物是视频文件,前面几篇主要讲的是手绘视频的创作部分,今天讲一下手绘视频的导出问题。主要以 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 端视频导出的问题,以及目前我们想到的解决方案,如果大家有更好的办法,欢迎反馈给我们,感谢!
上一篇文章           查看所有文章
加:2017-10-24 23:22:47  更:2017-10-24 23:22:49 
 
  WinRT-Metro 最新文章
背水一战 Windows 10 (76)
背水一战 Windows 10 (75)
uwp ListView列表滑动特效
背水一战 Windows 10 (74)
背水一战 Windows 10 (73)
背水一战 Windows 10 (72)
UWP 手绘视频创作工具技术分享系列
13、在 uwp应用中,给图片添加高斯模糊滤镜
Win2D学习系列(一):HelloWin2D
背水一战 Windows 10 (7)
技术频道: 站长资讯 .NET新手区 ASP.NET C# WinForm Silverlight WCF CLR WPF XNA Visual Studio ASP.NET MVC .NET控件开发 Entity Framework WinRT/Metro Java C++ PHP Delphi Python Ruby C语言 Erlang Go Swift Scala R语言 Verilog 其它语言 架构设计 面向对象 设计模式 领域驱动设计 Html/Css JavaScript jQuery HTML5 SharePoint GIS技术 SAP Oracle ERP Dynamics CRM K2 BPM 信息安全 企业信息化其他 Android开发 iOS开发 Windows Phone Windows Mobile 其他手机开发 敏捷开发 项目与团队管理 软件工程其他 SQL Server Oracle MySQL NoSQL 其它数据库 Windows 7 Windows Server Linux
脚本语言: vbs/VBScript DOS/BAT hta htc python perl 游戏相关 VBA 远程脚本 ColdFusion ruby专题 autoit seraphzone PowerShell linux shell Lua Golang Erlang 其它教程
网站开发: CSS/HTML/Xhtml html5 CSS XML/XSLT Dreamweaver教程 经验交流 开发者乐园 Android开发资料
360图书馆 软件开发资料 文字转语音 购物精选 软件下载 新闻资讯 小游戏 Chinese Culture 股票 三丰软件 开发 中国文化 网文精选 阅读网 看图 日历 万年历 2018年9日历
2018-9-25 23:04:42
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT知识库