Unit 高效开发系列 - 第六章 Unity 视频播放、压缩、图片与视频互转
前言
Uinty高效开发系列主要包含一系列的Unity开发实例,主要来源于笔者的一个3D游戏项目和一个手机APP项目,适合利用Unity开发游戏或手机APP场景。
一、Unity 视频播放、压缩、图片与视频互转实现
- Unity 视频播放、压缩、图片与视频互转,支持windows、Android平台,Iphone没有测试过,理论上可以。
1.安卓平台文件访问权限设置
- 安卓平台访问手机平台需要有相应权限,安卓平台需要进行一些特殊处理,在“ProjectSettings\ProjectSettings.asset”文件设置ForceSDCardPermission 为1;
- 程序启动时执行RequestPermission请求存储读写权限:
public static void RequestPermission()
{
#if UNITY_ANDROID && !UNITY_EDITOR
string permissionr = UnityEngine.Android.Permission.ExternalStorageRead;
if (!UnityEngine.Android.Permission.HasUserAuthorizedPermission(permissionr))
{
UnityEngine.Android.Permission.RequestUserPermission(permissionr);
}
string permissionw = UnityEngine.Android.Permission.ExternalStorageWrite;
if (!UnityEngine.Android.Permission.HasUserAuthorizedPermission(permissionw))
{
UnityEngine.Android.Permission.RequestUserPermission(permissionw);
}
#endif
}
2.安卓平台文件单选、多选,图片、视频文件加载
public struct ParaStrc
{
public string path;
public GameObject go;
public ParaStrc(string _path, GameObject _go)
{
path = _path;
go = _go;
}
}
public void GetImagePath(string imagePath, Image img,ref List<string> lstPath)
{
Debug.Log("GetImagePath");
if (imagePath == null)
return;
if (img != null)
{
string strpath = imagePath;
if (strpath.IndexOf(".jpg") > 0 || strpath.IndexOf(".JPG") > 0)
{
ChangeJpgToPng(strpath);
}
strpath = strpath.Replace(".jpg", ".png");
strpath = strpath.Replace(".JPG", ".png");
lstPath.Add(strpath);
ParaStrc para = new ParaStrc(strpath, img.gameObject);
StartCoroutine("LoadImage", (object)para);
}
}
public void GetImagePaths(string[] imagePaths,Image[] lstImg, ref List<string> lstPath)
{
Debug.Log("GetImagePath");
if (imagePaths == null)
return;
int idx = 0;
foreach (string strpath in imagePaths)
{
if (lstPath.Count < 5)
{
GetImagePath(strpath, lstImg[lstPath.Count],ref lstPath);
}
else
{
break;
}
}
}
private IEnumerator LoadImage(object paraIn)
{
ParaStrc para =(ParaStrc)paraIn;
Debug.Log("LoadImage:" + para.path);
WWW www = new WWW("file://" + para.path);
yield return www;
if (www.error == null)
{
Image img = para.go.transform.GetComponent<Image>();
if(img != null)
{
Debug.Log("img.sprite != null");
img.sprite = Texture2D2Sprite( www.texture);
}
else {
Debug.Log("img == null");
}
}
else
{
Debug.Log("LoadImage>>>www.error:");
Debug.LogError("LoadImage>>>www.error:" + www.error);
}
}
private void selectPic
_Android()
{
g_androidFileSystem.OpenAndroidFile((filePath) => {
if (filePath.IndexOf("|") > 0)
{
string[] paths = filePath.Split('|');
GetImagePaths(paths,g_picImages, ref g_picPaths);
}
else
{
string strpath = filePath;
Debug.Log("strpath:" + strpath);
if(g_picPaths.Count < 5)
{
GetImagePath(strpath, g_picImages[g_picPaths.Count],ref g_picPaths);
}
}
},AndriodFileTypeEnum.AFT_Picture,true );
}
3.播放视频
unity 播放视频通常需要引入插件,笔者用的AVPro Video是在商城买的,时间有点久,忘记多少钱了。
public void OnMuteChange()
{
if (PlayingPlayer)
{
PlayingPlayer.Control.MuteAudio(g_MuteToggle.isOn);
}
}
public void OnPlayButton()
{
if (PlayingPlayer)
{
PlayingPlayer.Control.Play();
}
}
public void OnPauseButton()
{
if (PlayingPlayer)
{
PlayingPlayer.Control.Pause();
}
}
public void OnVideoSeekSlider()
{
if (PlayingPlayer && g_videoSeekSlider && g_videoSeekSlider.value != g_setVideoSeekSliderValue)
{
PlayingPlayer.Control.Seek(g_videoSeekSlider.value * PlayingPlayer.Info.GetDurationMs());
}
}
public void OnVideoSliderDown()
{
if (PlayingPlayer)
{
g_wasPlayingOnScrub = PlayingPlayer.Control.IsPlaying();
if (g_wasPlayingOnScrub)
{
PlayingPlayer.Control.Pause();
}
OnVideoSeekSlider();
}
}
public void OnVideoSliderUp()
{
if (PlayingPlayer && g_wasPlayingOnScrub)
{
PlayingPlayer.Control.Play();
g_wasPlayingOnScrub = false;
}
}
public void OnRewindButton()
{
if (PlayingPlayer)
{
PlayingPlayer.Control.Rewind();
}
}
3.图片压缩成Mp4
笔者在一个项目中需要客户端上传大量图片到服务器存储,花了大量时间研究图片高保真压缩算法,最后研究发现,把图片压缩成MP4是压缩比最高的方案。如下图所示,5张图片总大小2.8M,压缩成MP4后大小为174k,压缩比达16.25倍。
- 需要特别说明一下,FFmpeg在Android平台压缩多张jpg图片时,只能保存一张图,windows平台下每问题,为解决Android平台多张Jgp压缩问题,示例工程会先将JPG转换为PNG。
public static void ChangeJpgToPng(string path)
{
List<string> cmds = new List<string>();
cmds.Add("-y");
cmds.Add("-i");
cmds.Add(path);
string outpath = path.Replace(".jpg", ".png");
cmds.Add(outpath);
Wrapper.Execute(cmds.ToArray());
int cnt = 0;
while (FFmpegWrapper.isFinish == false && cnt < 20)
{
Thread.Sleep(500);
cnt++;
}
if (File.Exists(outpath))
{
Debug.Log("!!!!!!!!! File.Exists,cnt:" + cnt);
}
}
4.Mp4解压成图片
步骤3中压缩的MP4解压还原成图片,总大小1.7M,占原始图片的60%大小。压缩前后图片效果无明显差异:
4.视频文件压缩
视频文件压缩也采用FFmpeg进行处理,视频压缩可调整压缩参数调整压缩比:
二、示例工程编译及运行
- 解压VedioPro.zip文件,使用unity 2019.2.2f1版本打开VedioPro文件夹。
三、资源下载
- 获取示例工程资源
链接:https://pan.baidu.com/s/1vnFc_H84B7V92nK6_wa3hA?pwd=a1r2 提取码:a1r2 - 获取解压密码
链接:http://jiajiatong.store/target.html?id=10 - 上一章
链接:Unit 高效开发系列 - 第五章 Unity UI实现模拟书籍,真实纸质书感,翻页动作丝滑顺畅 - 下一章
链接:Unit 高效开发系列 - 第七章 基于微信和支付宝登录