关于Unity视频资源打包AssetBundle在安卓平台上无法正常播放的问题及解决方案

首先了解一下Unity在进行AssetBundle打包时的几种构建方式:

  • BuildAssetBundleOptions.None:默认构建AssetBundle的方式。使用LZMA算法压缩,此算法压缩包小,但是加载时间长,而且使用之前必须要整体解压。解压以后,这个包又会使用LZ4算法重新压缩,这样这种包就不要对其整体解压了。(也就是第一次解压很慢,之后就变快了。
  • BuildAssetBundleOptions.UncompressedAssetBundle:不压缩数据,包大,但是加载很快。
  • BuildAssetBundleOptions.ChunkBaseCompression:使用LZ4算法压缩,压缩率没有LZMA高,但是加载资源不必整体解压。

而在安卓手机上加载AssetBundle中的视频资源时的报错就是由于unity在打包AssetBundle时对视频资源进行了压缩。

AndroidVideoMedia::OpenExtractor could not translate archive:/CAB-78qwdyh8739dh8uf02332dd686137/CAB-5b4cd5489dv87h2s93r7de1548fr7.resource to local file. Make sure file exists, is on disk (not in memory) and not compressed.
AndroidVideoMedia: Error opening extractor: -10004

解决方案一:对视频资源打包时不进行压缩,采用

BuildPipeline.BuildAssetBundles(…, BuildAssetBundleOptions. UncompressedAssetBundle,.. );

假如视频资源较大会导致游戏热更时需要下载的资源包体积也较大。

解决方案二:视频资源放服务器,在游戏中用代码动态下载视频到本地播放。

 

UIPlayVideo.lua.txt
local Parent = require("Manager/XYObj")
local CLASSNAME = "UIPlayVideo"
local CurObj = class(CLASSNAME,Parent)
local UiLayerConf = require "Manager/UiLayerConf"
local LoadVideoTool = require "Tool/LoadVideoTool"

function CurObj:ctor(CLASSNAME,CSharpObj)
	CurObj.super.ctor(self,CLASSNAME,CSharpObj)
	self.m_bUiLayerType = UiLayerConf.ui_type_dlg
end

--初始化
function CurObj:OnInit()
	btnClose.onClick:AddListener(function ()
		self:playVideoFun(videoConst.stop)
		ObjMgr:CloseUI("UIPlayVideo")
	end)
end

--每次展示执行一次
function CurObj:OnShow()
	print("播放界面展示---")
	self:playVideoFun(videoConst.play)

	btnClose.gameObject:SetActive(false)
	self:invoke(function ()
		btnClose.gameObject:SetActive(true)
	end , 5)

	self:invoke(function ()
		ObjMgr:CloseUI("UIPlayVideo")
	end , 23)
end


function CurObj:playVideoFun(state)
	if state == videoConst.play then
		local url = "video_url_temp"
		objVideoCom.url = url
		local succCallback = function(args)
			objVideoCom.url = args
			objVideoCom:Play()
		end
		local failCallback = function(...)
			ObjMgr:ShowTips("播放失败")
		end
		LoadVideoTool:LoadVideoUrl(url,succCallback,failCallback)
	else
		objVideoCom:Stop()
	end
end

videoConst = {
	play = 1,
	stop = 2
}

LoadVideoTool.lua.txt
local LoadVideoTool={}
local cs_coroutine = require "XLua/Common/cs_coroutine"
local crypt = require "crypt"
local UnityWebRequest =	CS.UnityEngine.Networking.UnityWebRequest
local File=CS.System.IO.File

local FuncEncodeURI
local FuncGetPlatformPath
local path

function LoadVideoTool:LoadVideoUrl(url,succCallback,failCallback)
	if not url or url == "" then
		print("error:输入的URL错误!")
		LoadFailCall(failCallback)
		return
	end
	if not path then
		path = FuncGetPlatformPath()
	end
	local urlEncode = FuncEncodeURI(url)
	urlEncode  = path .. "/" .. urlEncode..".mp4"

	if File.Exists(urlEncode) then
		-- 从本地加载
		--print("----------本地加载------------",url,urlEncode)
		if succCallback then
			succCallback(urlEncode)
		end
	else 
		--按网址下载
		--print("----------网上加载------------")
		cs_coroutine.start(function  ()
			local webRequest = UnityWebRequest.Get(url)
			webRequest.method = UnityWebRequest.kHttpVerbGET
			coroutine.yield(webRequest:SendWebRequest())
			if (not webRequest.isNetworkError and webRequest.responseCode == 200) then
				File.WriteAllBytes(urlEncode,webRequest.downloadHandler.data)
				if succCallback then
					succCallback(urlEncode)
				end
			else
				print("errorVideo : ",webRequest.error)
				LoadFailCall(failCallback)
			end
		end)
	end
end

-- 加载失败设置
LoadFailCall = function(failCallback)
	if failCallback then
		failCallback()
	end
end

--- 根据平台 获取 路径
FuncGetPlatformPath = function()
	return CS.UnityEngine.Application.temporaryCachePath
end

--- 网址中的特殊字符转换
FuncEncodeURI = function (s)
    return crypt.base64encode(s)
end

return LoadVideoTool

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值