2018-10-10VideoPlayer

目標:

播放網(wǎng)絡視頻远寸、本地視頻屠凶;可以暫停矗愧、前后拖動、快進夜涕、快退女器、音量調(diào)節(jié)住诸、下一個視頻

環(huán)境:

Unity5.6以上

VideoPlayer 介紹:

Unity正式發(fā)布了5.6版本后,作為5.x版本的最后一版還是有不少給力的更新的入桂。其中新加入了一個Video Player控件驳阎,用以取代之前的MovieTexture搞隐。

VideoPlayer API

VideoClip API

首先導入視頻劣纲,因為默認不進行編碼轉換谁鳍,現(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)絡視頻播放:

將網(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

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末次员,一起剝皮案震驚了整個濱河市淑蔚,隨后出現(xiàn)的幾起案子愕撰,更是在濱河造成了極大的恐慌搞挣,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,627評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異舍肠,居然都是意外死亡翠语,警方通過查閱死者的電腦和手機啡专,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評論 3 399
  • 文/潘曉璐 我一進店門们童,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鲸鹦,“玉大人馋嗜,你說我怎么就攤上這事「誓ィ” “怎么了济舆?”我有些...
    開封第一講書人閱讀 169,346評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長签夭。 經(jīng)常有香客問我第租,道長我纪,這世上最難降的妖魔是什么浅悉? 我笑而不...
    開封第一講書人閱讀 60,097評論 1 300
  • 正文 為了忘掉前任仇冯,我火速辦了婚禮苛坚,結果婚禮上,老公的妹妹穿的比我還像新娘等缀。我一直安慰自己,他們只是感情好娇昙,可當我...
    茶點故事閱讀 69,100評論 6 398
  • 文/花漫 我一把揭開白布尺迂。 她就那樣靜靜地躺著,像睡著了一般冒掌。 火紅的嫁衣襯著肌膚如雪噪裕。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,696評論 1 312
  • 那天股毫,我揣著相機與錄音膳音,去河邊找鬼。 笑死祭陷,一個胖子當著我的面吹牛苍凛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播兵志,決...
    沈念sama閱讀 41,165評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼醇蝴,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了想罕?” 一聲冷哼從身側響起哑蔫,我...
    開封第一講書人閱讀 40,108評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎弧呐,沒想到半個月后闸迷,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,646評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡俘枫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,709評論 3 342
  • 正文 我和宋清朗相戀三年腥沽,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鸠蚪。...
    茶點故事閱讀 40,861評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡今阳,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出茅信,到底是詐尸還是另有隱情盾舌,我是刑警寧澤,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布蘸鲸,位于F島的核電站妖谴,受9級特大地震影響,放射性物質發(fā)生泄漏酌摇。R本人自食惡果不足惜膝舅,卻給世界環(huán)境...
    茶點故事閱讀 42,196評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望窑多。 院中可真熱鬧仍稀,春花似錦、人聲如沸埂息。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽千康。三九已至享幽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間吧秕,已是汗流浹背琉闪。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留砸彬,地道東北人颠毙。 一個月前我還...
    沈念sama閱讀 49,287評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像砂碉,于是被迫代替她去往敵國和親蛀蜜。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,860評論 2 361

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,324評論 25 707
  • ¥開啟¥ 【iAPP實現(xiàn)進入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個線程增蹭,因...
    小菜c閱讀 6,450評論 0 17
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理滴某,服務發(fā)現(xiàn),斷路器滋迈,智...
    卡卡羅2017閱讀 134,716評論 18 139
  • 出差在外霎奢,無法稱量。
    潘潘_ef11閱讀 131評論 0 0
  • 亦舒的《我的前半生》跟著電視劇又火了一把饼灿。對于我們這代讀亦舒的女生來說幕侠,可能電視劇的改編還算不上合格,但是能以這種...
    小綾閱讀 522評論 0 1