目標:
播放網(wǎng)絡視頻远寸、本地視頻屠凶;可以暫停矗愧、前后拖動、快進夜涕、快退女器、音量調(diào)節(jié)住诸、下一個視頻
Unity5.6以上
Unity正式發(fā)布了5.6版本后,作為5.x版本的最后一版還是有不少給力的更新的入桂。其中新加入了一個Video Player控件驳阎,用以取代之前的MovieTexture搞隐。
首先導入視頻劣纲,因為默認不進行編碼轉換谁鳍,現(xiàn)在的視頻導入速度比以前快很多倘潜。
在視頻的Import Settings面板上涮因,我們可以選擇導入的版本是新的VideoClip或者是舊版的MovieTexture养泡。同時可以設置編碼轉換,轉換的速度視視頻的大小而定购披。
Unity5.6提供了多種生成Video Player控件的方式:
新建一個空白的Video Player:選擇菜單欄的GameObject->Video->Video Player或者在Hierarchy面板上選擇Create->Video->Video Player或者右擊Hierarchy面板空白處選擇Video->Video Player刚陡。
直接將導入的VideoClip拖入場景或者Hierarchy面板株汉,生成的VideoPlayer控件的VideoClip將會自動被賦值乔妈,如果場景中存在MainCamera,Camera也會被自動賦值為MainCamera贮懈。
將導入的VideoClip拖動到場景中的Camera物體上朵你,生成的VideoPlayer控件的VideoClip和MainCamera將會自動被賦值抡医,模式默認選擇Camera Far Plane。
將導入的VideoClip拖動到場景中的2D或者3D物體上大脉,生成的VideoPlayer控件的VideoClip和Renderer將會自動被賦值镰矿,模式默認選擇Material Override俘种。
將導入的VideoClip拖動到場景中的UI物體上宙刘,生成的VideoPlayer控件的VideoClip將會自動被賦值悬包,模式默認選擇Render Texture。
下面是一些比較大眾化的設置:
Play On Awake:腳本載入時自動播放。
Wait For First Frame:決定是否在第一幀加載完成后才播放饶号,只有在Play On Awake被勾選是才有效茫船∨てǎ可以防止視頻最前幾幀被跳過料滥。(使用過程中發(fā)現(xiàn)勾選后視頻無法自動播放葵腹,原因不明)
Loop:循環(huán)屿岂。
Playback Speed:播放速度爷怀。
Video Player還提供了多種視頻渲染的方式运授,包括Camera Far Plane乔煞,Camera Near Plane渡贾,Render Texture,Material Override锦溪,Api Only。
Camera Far Plane:基于攝像機的渲染牺丙,渲染在攝像機的遠平面上冲簿,需要設置用于渲染的攝像機亿昏,同時可以修改alpha通道的值做透明效果角钩,可用于背景播放器。
Camera Near Plane:基于攝像機的渲染,渲染在攝像機的近平面上辫愉,需要設置用于渲染的攝像機将硝,同時可以修改alpha通道的值做透明效果,可用作前景播放器闸衫。
Render Texture:將視頻畫面保存在Render Texture上蔚出,以供物體或者RawImage使用虫腋,可以用來做基于UGUI的播放器悦冀。
Material Override:將視頻畫面復制給所選Render的Material盒蟆。需要選擇具有Render組件的物體历等,可以選擇賦值的材質屬性〖瞿恚可制作360全景視頻和VR視頻处面。
Api Only: API上面也沒給出說明魂角,暫時不知智绸。
直接將視頻拖到VideoClip上
這個時候就可以播放了囱挑。
將網(wǎng)絡視頻的鏈接寫到URL上面
這個時候就可以播放了
也可以通過URL播放本地視頻平挑,Browse...可以選擇本地視頻的路徑通熄,并且自動生成URL
這個時候我們會發(fā)現(xiàn)唇辨,播放的時候沒有聲音。
我們只要添加一個Audio Source組件亡驰,將他賦給VideoPlayer里面的Audio Source就有聲音了
腳本控制(需引用UnityEngine.Video):
VideoPlayer的腳本控制與AudioSource相似,有常規(guī)的Play栗恩,Pause磕秤,Stop方法市咆,也有用于進度控制的time,isPlaying客情,isLooping,frame梭伐,frameCount等屬性糊识。
VideoPlayer可以使用一系列事件來監(jiān)聽播放的各個動作:
errorReceived: 錯誤監(jiān)聽到時被執(zhí)行赂苗。
frameDropped :有丟幀發(fā)生時被執(zhí)行。
frameReady :新的一幀準備好時被執(zhí)行朴沿。
loopPointReached :播放結束或播放到循環(huán)的點時被執(zhí)行赌渣。
prepareCompleted :視頻準備完成時被執(zhí)行。
seekCompleted :查詢幀操作完成時被執(zhí)行览芳。
started:在Play方法調(diào)用之后立刻調(diào)用沧竟。
一開始我是動態(tài)去獲取視頻路徑
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Video;
public class MyVideo : MonoBehaviour {
? ? public VideoPlayer vPlayer;
? ? public AudioSource source;
? ? public string url = "http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4";
? ? private void Awake()
? ? {
? ? ? ? vPlayer = GetComponent<VideoPlayer>();
? ? ? ? source = GetComponent<AudioSource>();
? ? }
? ? // Use this for initialization
? ? void Start () {
? ? ? ? if (vPlayer != null)
? ? ? ? {
? ? ? ? ? ? vPlayer.source = VideoSource.Url;
? ? ? ? ? ? vPlayer.url = url;
? ? ? ? ? ? //添加音頻到VideoPlayer
? ? ? ? ? ? vPlayer.SetTargetAudioSource(0, source);
? ? ? ? ? ? vPlayer.prepareCompleted += Prepared;
? ? ? ? ? ? vPlayer.Prepare();
? ? ? ? }
}
// Update is called once per frame
void Update () {
}
? ? void Prepared(VideoPlayer player)
? ? {
? ? ? ? player.Play();
? ? }
}
可是我發(fā)現(xiàn)視頻可以播放了屯仗,但是聲音始終都沒有魁袜。于是峰弹,我就改成了動態(tài)添加組件的方式
? ? private void Awake()
? ? {
? ? ? ? vPlayer = transform.gameObject.AddComponent<VideoPlayer>();
? ? ? ? source = transform.gameObject.AddComponent<AudioSource>();
? ? ? ? vPlayer.playOnAwake = false;
? ? ? ? source.playOnAwake = false;
? ? }
這樣就可以視頻和音頻一起播放了鞠呈。
可以通過VideoPlayer的time這個函數(shù)來控制視頻的播放進度
? ? private void ChangeVideo() {
? ? ? ? //前進20秒
? ? ? ? vPlayer.time += 20f;
? ? ? ? //后退20秒
? ? ? ? vPlayer.time -= 20f;
? ? }
Audio Source的volume控制音量的大小
? ? private void ChangeAudio() {
? ? ? ? //聲音加20
? ? ? ? source.volume += 20f;
? ? ? ? //聲音-20
? ? ? ? source.volume -= 20f;
? ? }
綜上所述右钾,我們就能做出一個完整的視頻播放了
整合最終版代碼:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Video;
using UnityEngine.UI;
using System;
public class VideoPlayerTeach : MonoBehaviour {
? ? //圖像
? ? public RawImage image;
? ? //播放器
? ? public VideoPlayer vPlayer;
? ? public string urlNetWork = "http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4";//網(wǎng)絡視頻路徑
? ? //播放
? ? public Button btn_Play;
? ? //暫停
? ? public Button btn_Pause;
? ? //前進
? ? public Button btn_Fornt;
? ? //后退
? ? public Button btn_Back;
? ? //下一個
? ? public Button btn_Next;
? ? //視頻控制器
? ? public Slider sliderVideo;
? ? //音量控制器
? ? public Slider sliderSource;
? ? //音量大小
? ? public Text text;
? ? //當前視頻時間
? ? public Text text_Time;
? ? //視頻總時長
? ? public Text text_Count;
? ? //音頻組件
? ? public AudioSource source;
? ? //需要添加播放器的物體
? ? public GameObject obj;
? ? //是否拿到視頻總時長
? ? public bool isShow;
? ? //前進后退的大小
? ? public float numBer = 20f;
? ? //時 分的轉換
? ? private int hour, mint;
? ? private float time;
? ? private float time_Count;
? ? private float time_Current;
? ? //視頻是否播放完成
? ? private bool isVideo;
? ? // Use this for initialization
? ? void Start () {
? ? ? ? image = obj.GetComponent<RawImage>();
? ? ? ? //一定要動態(tài)添加這兩個組件窘茁,要不然會沒聲音
? ? ? ? vPlayer = obj.AddComponent<VideoPlayer>();
? ? ? ? source = obj.AddComponent<AudioSource>();
? ? ? ? //這3個參數(shù)不設置也會沒聲音 喚醒時就播放關閉
? ? ? ? vPlayer.playOnAwake = false;
? ? ? ? source.playOnAwake = false;
? ? ? ? source.Pause();
? ? ? ? //初始化
? ? ? ? Init(urlNetWork);
? ? ? ? btn_Play.onClick.AddListener(delegate { OnClick(0); });
? ? ? ? btn_Pause.onClick.AddListener(delegate { OnClick(1); });
? ? ? ? btn_Fornt.onClick.AddListener(delegate { OnClick(2); });
? ? ? ? btn_Back.onClick.AddListener(delegate { OnClick(3); });
? ? ? ? btn_Next.onClick.AddListener(delegate { OnClick(4); });
? ? ? ? sliderSource.value = source.volume;
? ? ? ? text.text = string.Format("{0:0}%", source.volume * 100);
? ? ? ? sliderSource.onValueChanged.AddListener(delegate { ChangeSource(sliderSource.value); });
? ? }
? ? /// <summary>
? ? ///? ? 初始化VideoPlayer
? ? /// </summary>
? ? /// <param name="url"></param>
? ? private void Init(string url) {
? ? ? ? isVideo = true;
? ? ? ? isShow = true;
? ? ? ? time_Count = 0;
? ? ? ? time_Current = 0;
? ? ? ? sliderVideo.value = 0;
? ? ? ? //設置為URL模式
? ? ? ? vPlayer.source = VideoSource.Url;
? ? ? ? //設置播放路徑
? ? ? ? vPlayer.url = url;
? ? ? ? //在視頻中嵌入的音頻類型
? ? ? ? vPlayer.audioOutputMode = VideoAudioOutputMode.AudioSource;
? ? ? ? //把聲音組件賦值給VideoPlayer
? ? ? ? vPlayer.SetTargetAudioSource(0, source);
? ? ? ? //當VideoPlayer全部設置好的時候調(diào)用
? ? ? ? vPlayer.prepareCompleted += Prepared;
? ? ? ? //啟動播放器
? ? ? ? vPlayer.Prepare();
? ? }
? ? /// <summary>
? ? ///? ? 改變音量大小
? ? /// </summary>
? ? /// <param name="value"></param>
? ? public void ChangeSource(float value) {
? ? ? ? source.volume = value;
? ? ? ? text.text = string.Format("{0:0}%", value * 100);
? ? }
? ? /// <summary>
? ? ///? ? 改變視頻進度
? ? /// </summary>
? ? /// <param name="value"></param>
? ? public void ChangeVideo(float value) {
? ? ? ? if (vPlayer.isPrepared)
? ? ? ? {
? ? ? ? ? ? vPlayer.time = (long)value;
? ? ? ? ? ? Debug.Log("VideoPlayer Time:"+vPlayer.time);
? ? ? ? ? ? time = (float)vPlayer.time;
? ? ? ? ? ? hour = (int)time / 60;
? ? ? ? ? ? mint = (int)time % 60;
? ? ? ? ? ? text_Time.text = string.Format("{0:D2}:{1:D2}", hour.ToString(), mint.ToString());
? ? ? ? }
? ? }
? ? private void OnClick(int num) {
? ? ? ? switch (num)
? ? ? ? {
? ? ? ? ? ? case 0:
? ? ? ? ? ? ? ? vPlayer.Play();
? ? ? ? ? ? ? ? Time.timeScale = 1;
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? case 1:
? ? ? ? ? ? ? ? vPlayer.Pause();
? ? ? ? ? ? ? ? Time.timeScale = 0;
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? case 2:
? ? ? ? ? ? ? ? sliderVideo.value = sliderVideo.value + numBer;
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? case 3:
? ? ? ? ? ? ? ? sliderVideo.value = sliderVideo.value - numBer;
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? case 4:
? ? ? ? ? ? ? ? vPlayer.Stop();
? ? ? ? ? ? ? ? Init(Application.streamingAssetsPath + "/EasyMovieTexture.mp4");
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? default:
? ? ? ? ? ? ? ? break;
? ? ? ? }
? ? }
? ? // Update is called once per frame
? ? void Update ()
? ? {
? ? ? ? if (vPlayer.isPlaying && isShow)
? ? ? ? {
? ? ? ? ? ? //把圖像賦給RawImage
? ? ? ? ? ? image.texture = vPlayer.texture;
? ? ? ? ? ? //幀數(shù)/幀速率=總時長? ? 如果是本地直接賦值的視頻驼抹,我們可以通過VideoClip.length獲取總時長
? ? ? ? ? ? sliderVideo.maxValue = vPlayer.frameCount/vPlayer.frameRate;
? ? ? ? ? ? time = sliderVideo.maxValue;
? ? ? ? ? ? hour = (int)time / 60;
? ? ? ? ? ? mint = (int)time % 60;
? ? ? ? ? ? text_Count.text = string.Format("/? {0:D2}:{1:D2}", hour.ToString(), mint.ToString());
? ? ? ? ? ? sliderVideo.onValueChanged.AddListener(delegate { ChangeVideo(sliderVideo.value); });
? ? ? ? ? ? isShow = !isShow;
? ? ? ? }
? ? ? ? if (Mathf.Abs((int)vPlayer.time - (int)sliderVideo.maxValue) == 0)
? ? ? ? {
? ? ? ? ? ? vPlayer.frame = (long)vPlayer.frameCount;
? ? ? ? ? ? vPlayer.Stop();
? ? ? ? ? ? Debug.Log("播放完成框冀!");
? ? ? ? ? ? isVideo = false;
? ? ? ? ? ? return;
? ? ? ? }
? ? ? ? else if (isVideo)
? ? ? ? {
? ? ? ? ? ? time_Count += Time.deltaTime;
? ? ? ? ? ? if ((time_Count - time_Current) >= 1)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? sliderVideo.value += 1;
? ? ? ? ? ? ? ? Debug.Log("value:" + sliderVideo.value);
? ? ? ? ? ? ? ? time_Current = time_Count;
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ? private void FixedUpdate()
? ? {
? ? }
? ? void Prepared(VideoPlayer player) {
? ? ? ? player.Play();
? ? }
}
這樣就實現(xiàn)了完整的播放明也,完美诡右!PC端,移動端測試完美運行(IOS還沒測)域那!
下載示例工程:
鏈接:https://pan.baidu.com/s/1gfkWCyZ密碼: tsuk