共用方式為


HoloLens (第 1 代) 和 Azure 306:串流影片


注意

混合實境學院教學課程的設計是以 HoloLens (第 1 代) 和混合實境沉浸式頭戴裝置為準。 因此,對於仍在尋找這些裝置開發指引的開發人員而言,我們覺得這些教學課程很重要。 這些教學課程不會使用用於 HoloLens 2 的最新工具組或互動進行更新。 系統會保留這些資訊,以繼續在支援的裝置上運作。 未來將會張貼一系列新的教學課程,以示範如何為 HoloLens 2 進行開發。 張貼這些教學課程的連結將會更新此通知。


Windows Mixed Reality V R 範例的螢幕快照。Windows Mixed Reality V R 體驗的螢幕快照。

在此課程中,您將瞭解如何將 Azure 媒體服務 連線到 Windows Mixed Reality VR 體驗,以允許在沉浸式頭戴裝置上播放 360 度視訊。

Azure 媒體服務 是一系列服務,可讓您廣播質量的視訊串流服務,以在現今最受歡迎的行動裝置上觸及更多觀眾。 如需詳細資訊,請流覽 Azure 媒體服務 頁面

完成本課程之後,您將有混合實境沉浸式頭戴式裝置應用程式,其可以執行下列動作:

  1. 透過 Azure 媒體服務,從 Azure 儲存體 擷取 360 度影片。

  2. 在 Unity 場景中顯示擷取的 360 度視訊。

  3. 在兩個場景之間流覽,並搭配兩個不同的影片。

在您的應用程式中,您應該瞭解如何將結果與設計整合。 本課程旨在教導您如何整合 Azure 服務與 Unity 專案。 使用本課程中取得的知識來增強混合實境應用程式,是您的工作。

裝置支援

課程 HoloLens 沉浸式頭戴裝置
MR 和 Azure 306:串流影片 ✔️

必要條件

注意

本教學課程專為具備 Unity 和 C# 基本經驗的開發人員所設計。 另請注意,本檔內的必要條件和書面指示代表在撰寫期間經過測試和驗證的內容(2018 年 5 月)。 您可以自由使用最新的軟體,如安裝工具文章所列,不過不應該假設本課程中的資訊會完全符合您在較新的軟體中找到的內容,而不是下面所列的內容。

針對此課程,我們建議使用下列硬體和軟體:

在您開始使用 Intune 之前

  1. 為了避免建置此專案時發生問題,強烈建議您在根資料夾或近根資料夾中建立本教學課程中所提及的專案(長文件夾路徑在建置時可能會導致問題)。

  2. 設定及測試混合實境沉浸式頭戴式裝置。

    注意

    本課程不需要運動控制器。 如果您需要設定沈浸式頭戴式裝置的支援,請按兩下 如何設定 Windows Mixed Reality 的連結。

第 1 章 - Azure 入口網站:建立 Azure 儲存體 帳戶

若要使用 Azure 儲存體 服務,您必須在 Azure 入口網站 中建立和設定記憶體帳戶

  1. 登入 Azure 入口網站

    注意

    如果您還沒有 Azure 帳戶,則必須建立一個帳戶。 如果您在教室或實驗室情況中遵循本教學課程,請洽詢您的講師或其中一名監看員,以協助設定您的新帳戶。

  2. 登入之後,請按兩下 左側功能表中的 [記憶體帳戶 ]。

    Azure 入口網站功能表的螢幕快照。記憶體帳戶會反白顯示。

  3. 在 [ 記憶體帳戶] 索引標籤上,按兩下 [ 新增]。

    記憶體帳戶對話框的螢幕快照。[新增] 已醒目提示。

  4. 在 [ 建立記憶體帳戶] 索引標籤 中:

    1. 插入帳戶的 [名稱],請注意此欄位只接受數位和小寫字母。

    2. 針對 [部署模型],選取 [資源管理員]。

    3. 針對 [帳戶種類],選取 [記憶體][一般用途 v1]。

    4. 針對 [效能],選取 [ 標準]。*

    5. 針對 [復寫],選取 [本地備援記憶體 ][LRS]。

    6. 將 [安全傳輸] 保留[已停用]。

    7. 選取 [訂用帳戶]

    8. 選擇資源群組或建立新的群組。 資源群組提供一種方式來監視、控制存取、布建和管理 Azure 資產集合的計費。

    9. 判斷資源群組的位置(如果您要建立新的資源群組)。 在理想情況下,位置位於應用程式執行所在的區域中。 某些 Azure 資產僅適用於特定區域。

  5. 您必須確認您已瞭解此服務適用的條款和條件。

    [建立記憶體帳戶] 頁面的螢幕快照。

  6. 按兩下 [ 建立] 之後,您必須等候服務建立,這可能需要一分鐘的時間。

  7. 建立服務實例之後,入口網站中就會顯示通知。

    部署成功通知的螢幕快照。

  8. 此時,您不需要遵循資源,只要移至下一章即可。

第 2 章 - Azure 入口網站:建立媒體服務

若要使用 Azure 媒體服務,您必須將服務的實例設定為可供您的應用程式使用(其中帳戶持有者必須是系統管理員)。

  1. 在 Azure 入口網站中,按兩下左上角的 [ 建立資源 ],然後搜尋 媒體服務, 然後按 Enter。 您想要的資源目前有粉紅色圖示;按兩下此選項,即可顯示新的頁面。

    Azure 入口網站的螢幕快照。醒目提示 [媒體服務] 選項。

  2. 新頁面將提供媒體服務的描述。 在此提示的左下方,按兩下 [ 建立] 按鈕,以建立與這項服務的關聯。

    Azure 入口網站的螢幕快照。[建立] 按鈕會反白顯示。

  3. 點選 「 建立 面板」 後,會出現您需要提供新媒體服務的一些詳細資料:

    1. 插入此服務實例所需的 帳戶名稱

    2. 選取 [訂用帳戶]

    3. 選擇資源群組或建立新的群組。 資源群組提供一種方式來監視、控制存取、布建和管理 Azure 資產集合的計費。 建議將所有與單一專案相關聯的 Azure 服務(例如,例如這些實驗室)保留在通用資源群組之下。

    如果您想要深入瞭解 Azure 資源群組,請遵循此 連結以瞭解如何管理 Azure 資源群組

    1. 判斷資源群組的位置(如果您要建立新的資源群組)。 在理想情況下,位置位於應用程式執行所在的區域中。 某些 Azure 資產僅適用於特定區域。

    2. 針對 [ 記憶體帳戶] 區段,按兩下 [ 請選取...] 區段,然後按下 您在上一章中建立的記憶體帳戶

    3. 您也必須確認您已瞭解此服務適用的條款和條件。

    4. 按一下 [建立]

      [建立媒體服務帳戶] 頁面的螢幕快照。

  4. 按兩下 [ 建立] 之後,您必須等候服務建立,這可能需要一分鐘的時間。

  5. 建立服務實例之後,入口網站中就會顯示通知。

    入口網站功能表中通知圖示的螢幕快照。

  6. 按兩下通知以探索新的服務實例。

    成功部署通知的螢幕快照。

  7. 按兩下通知中的 [ 移至資源 ] 按鈕,以探索新的服務實例。

  8. 在新的媒體服務頁面中,按兩下左側 面板內的 [資產 ] 連結,大約在下方。

  9. 在下一個頁面上,按下一下一個頁面上,按下一面左上角的 [ 上傳]。

    [資產] 頁面的螢幕快照。[上傳] 和 [資產] 選項會反白顯示。

  10. 按兩下 [ 資料夾 ] 圖示以瀏覽您的檔案,然後選取您想要串流的前360個影片。

    您可以遵循此 連結來下載範例影片

    上傳影片資產頁面的螢幕快照。

警告

長檔名可能會導致編碼器發生問題:因此為了確保影片沒有問題,請考慮縮短視訊檔名的長度。

  1. 當影片完成上傳時,進度列會變成綠色。

    上傳影片資產進度列的螢幕快照。

  2. 按兩下文字 (yourservicename - Assets)以返回 [資產] 頁面。

  3. 您會發現影片已成功上傳。 按一下。

    [資產] 頁面的螢幕快照。影片 1 點 M P 4 已醒目提示。

  4. 您重新導向至的頁面會顯示影片的詳細資訊。 若要能夠使用您的視訊,您必須將它編碼,方法是按下 頁面左上角的 [編碼 ] 按鈕。

    資產頁面的螢幕快照。編碼按鈕會反白顯示。

  5. 新的面板會出現在右側,您可以在其中設定檔案的編碼選項。 設定下列屬性(部分屬性預設已設定):

    1. 媒體編碼器名稱 媒體編碼器標準

    2. 編碼默認 內容自適性多重比特率 MP4

    3. 作業名稱 媒體編碼器標準 處理Video1.mp4

    4. 輸出媒體資產名稱Video1.mp4 -- 媒體編碼器標準 編碼

      編碼資產頁面的螢幕快照。

  6. 按一下 [建立] 按鈕。

  7. 您會注意到已新增編碼作業的列,按兩下該列,並顯示一個面板,其中顯示編碼進度。

    已新增通知列編碼作業的螢幕快照。

    編碼器處理頁面的螢幕快照。

  8. 等候作業完成。 完成後,請放心關閉面板,並在該面板右上方使用 『X』 關閉面板。

    進度列的螢幕快照,其中已完成狀態。

    媒體編碼程式處理頁面頂端功能表的螢幕快照。

    重要

    這需要的時間,取決於視訊的檔案大小。 此程式可能需要相當長的時間。

  9. 現在已建立視訊的編碼版本,您可以加以發佈,使其可供存取。 若要這樣做,請按兩下藍色連結 [資產 ] 傳回 [資產] 頁面。

    Azure 入口網站的螢幕快照。資產連結會反白顯示。

  10. 您會看到您的影片,以及另一個影片,其為 資產類型 多比特率 MP4

    Microsoft Azure 資產功能表的螢幕快照。

    注意

    您可能會注意到,新資產與初始視訊一起為 未知,且其 大小為 『0』 個字節,只要重新整理視窗即可更新。

  11. 按兩下此新資產。

    目錄清單資產的螢幕快照。

  12. 您會看到與您先前使用的面板類似,只是這是不同的資產。 按兩下位於頁面頂端的 [ 發佈] 按鈕。

    頂端功能表欄的螢幕快照。[發佈] 按鈕會反白顯示。

  13. 系統會提示您設定 定位器,也就是資產中的檔案/秒進入點。 針對您的案例,請設定下列屬性:

    1. 定位器類型>漸進式。

    2. 日期時間將會為您設定,從您目前的日期到未來的時間(在此案例中為 100 年)。 請保持不變,或將其變更為適合。

    注意

    如需定位器的詳細資訊,以及您可以選擇的內容,請流覽 Azure 媒體服務 檔

  14. 在該面板底部,按兩下 [ 新增 ] 按鈕。

    顯示目錄清單與要發佈之資產對話框的螢幕快照。

  15. 您的影片現已發佈,而且可以使用其端點進行串流處理。 頁面的下一步是 [檔案] 區段。 這是視訊不同編碼版本的位置。 選取最高解析度一個 (在下圖中為 1920x960 檔案),然後會出現右側的面板。 您可以在該處找到下載 URL。 複製此 端點 ,因為您稍後會在程序代碼中使用。

    [Microsoft Azure 檔案儲存體] 區段的螢幕快照。

    資產資訊頁面的螢幕快照。

    注意

    您也可以按 [ 播放 ] 按鈕來播放影片並進行測試。

  16. 您現在必須上傳您將在此實驗室中使用的第二個影片。 請遵循上述步驟,針對第二個視訊重複相同的程式。 請確定您也會複製第二個 端點 。 使用下列 鏈接下載第二個影片

  17. 發佈這兩個影片之後,您就可以移至下一章。

第 3 章 - 設定 Unity 專案

以下是使用混合實境進行開發的一般設定,因此是其他專案的良好範本。

  1. 開啟 Unity ,然後按兩下 [ 新增]。

    Unity 專案索引標籤的螢幕快照。[新增] 按鈕會反白顯示。

  2. 您現在必須提供 Unity 項目名稱,插入 MR_360VideoStreaming。。 請確定專案類型已設定為 3D。 將 [位置] 設定為您適當的位置(請記住,更接近根目錄會更好)。 然後按兩下 [ 建立專案]。

    Unity 新項目頁面的螢幕快照。

  3. 在 Unity 開啟時,值得檢查預設 的腳本編輯器 設定為 Visual Studio。 移至 [ 編輯喜好設定 ],然後從新視窗流覽至 [外部工具]。 將外部腳本編輯器變更Visual Studio 2017。 關閉 [喜好設定] 視窗。

    外部腳本編輯器功能表的螢幕快照。已選取 Visual Studio 2017。

  4. 接下來,移至 [檔案建置設定],然後按兩下 [切換平臺] 按鈕,將平臺切換為 通用 Windows 平台

  5. 也請確定:

    1. 目標裝置 會設定為 [任何裝置]。

    2. 組建類型 設定為 D3D。

    3. SDK 會設定為 [最新安裝]。

    4. Visual Studio 版本 設定為 [最新安裝]。

    5. [建置並執行 ] 設定為 [ 本機計算機]。

    6. 別擔心現在設定 場景 ,因為您稍後會設定這些場景。

    7. 其餘的設定現在應該保留為預設值。

      Unity 組建設定畫面的螢幕快照。

  6. 在 [建置設定] 視窗中,按兩下 [播放程序設定] 按鈕,這會在 Inspector 所在的空間中開啟相關的面板。

  7. 在此面板中,需要驗證一些設定:

    1. 在 [ 其他設定] 索引標籤中:

      1. 腳本運行時間版本應該是穩定 (.NET 3.5 對等專案)。

      2. 腳本後端 應該是 .NET。

      3. API 相容性層級 應該是 .NET 4.6。

        顯示 [通用 Windows 平台] 頁面之 [設定] 的螢幕快照。

    2. 在面板的下方,在 [XR 設定] 中,勾選 [支援虛擬現實] 中的 [XR 設定],確定已新增 Windows Mixed Reality SDK

      Unity X R 設定畫面的螢幕快照。

    3. 在 [發佈設定] 索引標籤的 [功能] 底下,檢查:

      • InternetClient

        [功能] 畫面的螢幕快照。已檢查因特網用戶端。

  8. 進行這些變更之後,請關閉 [ 建置設定] 視窗。

  9. 儲存您的項目 儲存專案

第 4 章 - 匯入 InsideOutSphere Unity 套件

重要

如果您想要略過 本課程的 Unity 設定 元件,並繼續直接進入程式碼,請隨意下載此 .unitypackage、將它匯入您的專案做為 自定義套件,然後從 第 5 章繼續進行。 您仍然需要建立 Unity 專案。

針對本課程,您必須下載名為 InsideOutSphere.unitypackage 的 Unity 資產套件

如何匯入 unitypackage

  1. 使用您前面的 Unity 儀錶板,單擊 畫面頂端功能表中的 [資產 ],然後按兩下 [ 匯入套件 > 自定義套件]。

    資產功能表的螢幕快照。[匯入套件] 功能表隨即開啟。已選取 [自定義套件]。

  2. 使用檔案選擇器來選取 InsideOutSphere.unitypackage 套件,然後按兩下 [ 開啟]。 此資產的元件清單將會顯示給您。 按兩下 [匯入] 以確認匯入。

    [匯入 Unity 套件] 畫面的螢幕快照。

  3. 匯入完成後,您就會注意到已將三個新資料夾 [材料]、 [模型] 和 [預製專案] 新增至您的 Assets 資料夾。 這種資料夾結構通常適用於 Unity 專案。

    assets 資料夾的螢幕快照。

    1. 開啟 Models 資料夾,您會看到 InsideOutSphere 模型已匯入。

    2. [材質] 資料夾中,您會發現 InsideOutSpheres 材質 lambert1,以及一種名為 ButtonMaterial 的材料,該材質由 GazeButton 使用,您很快就會看到該材質。

    3. Prefabs 資料夾包含 InsideOutSphere 預製b,其中包含 InsideOutSphere 模型GazeButton

    4. 未包含任何程式代碼,您將遵循本課程撰寫程式代碼。

  4. 在 [ 階層] 中 ,選取 [主要相機 ] 物件,並更新下列元件:

    1. 轉換

      1. Position = X: 0, Y: 0, Z: 0.

      2. 旋轉 = X: 0, Y: 0, Z: 0。

      3. 縮放 X:1、 Y:1、 Z:1。

    2. 相機

      1. 清除旗標:純色。

      2. 裁剪平面:接近:0.1,遠:6。

        偵測器畫面的螢幕快照。

  5. 流覽至 Prefab 資料夾,然後將 InsideOutSphere 預製專案拖曳[階層面板]。

    Prefab 資料夾功能表和開發人員環境的螢幕快照。

  6. 單擊 [階層] 旁的小箭號,展開 Hierarchy 內的 InsideOutSphere 物件。 您會看到名為 GazeButton 的子物件。 這會用來變更場景,因此影片。

    階層索引標籤的螢幕快照。

  7. 在 [偵測器] 視窗中, 按兩下 InsideOutSphere 的 [轉換] 元件,確定已設定下列屬性:

轉換 - 位置

X Y Z
0 0 0

轉換 - 旋轉

X Y Z
0 50- 0

轉換 - 調整

X Y Z
0 0 0

[偵測器] 畫面的螢幕快照,其中已針對 [內側球體] 開啟。

  1. 按兩下 GazeButton 子物件,並設定其 Transform,如下所示:

轉換 - 位置

X Y Z
3.6 1.3 0

轉換 - 旋轉

X Y Z
0 0 0

轉換 - 調整

X Y Z
1 1 1

開啟場景索引標籤的螢幕快照。

第 5 章 - 建立 VideoController 類別

VideoController 類別會裝載兩個影片端點,這些端點將用來串流來自 Azure 媒體服務的內容。

若要建立此類別:

  1. 以滑鼠右鍵按兩下位於 [項目面板] 的 [資產資料夾],然後按兩下 [建立>資料夾]。 將資料夾 命名為文稿

    資產資料夾功能表的螢幕快照。[建立] 功能表隨即開啟,並選取資料夾。

    專案索引標籤的螢幕快照。已選取 [資產] 資料夾。

  2. 按兩下 [文稿] 資料夾以開啟它。

  3. 在資料夾內按下滑鼠右鍵,然後按兩下 [ 建立 > C# 腳本]。 將腳本 命名為 VideoController

    名為影片控制器的檔案螢幕快照。

  4. 按兩下新的 VideoController 腳本,以使用 Visual Studio 2017 開啟它。

    影片控制器檔案程式代碼的螢幕快照。

  5. 更新程式代碼檔案頂端的命名空間,如下所示:

    using System.Collections;
    using UnityEngine;
    using UnityEngine.SceneManagement;
    using UnityEngine.Video;
    
  6. 在 VideoController 類別中輸入下列變數,以及 Awake() 方法:

        /// <summary> 
        /// Provides Singleton-like behaviour to this class. 
        /// </summary> 
        public static VideoController instance; 
    
        /// <summary> 
        /// Reference to the Camera VideoPlayer Component.
        /// </summary> 
        private VideoPlayer videoPlayer; 
    
        /// <summary>
        /// Reference to the Camera AudioSource Component.
        /// </summary> 
        private AudioSource audioSource; 
    
        /// <summary> 
        /// Reference to the texture used to project the video streaming 
        /// </summary> 
        private RenderTexture videoStreamRenderTexture;
    
        /// <summary>
        /// Insert here the first video endpoint
        /// </summary>
        private string video1endpoint = "-- Insert video 1 Endpoint here --";
    
        /// <summary>
        /// Insert here the second video endpoint
        /// </summary>
        private string video2endpoint = "-- Insert video 2 Endpoint here --";
    
        /// <summary> 
        /// Reference to the Inside-Out Sphere. 
        /// </summary> 
        public GameObject sphere;
    
        void Awake()
        {
            instance = this;
        }
    
  7. 現在是時候從您的 Azure 媒體服務影片輸入端點:

    1. video1endpoint 變數中的第一個 。

    2. video2endpoint 變數中的第二個 。

    警告

    在 Unity 中使用 HTTPs 與 2017.4.1f1 版有已知問題。 如果影片在播放時提供錯誤,請嘗試改用 『HTTP』。

  8. 接下來, 必須編輯 Start() 方法。 每次使用者切換場景時,都會觸發這個方法(因此切換視訊),方法是查看 [注視按鈕]。

        // Use this for initialization
        void Start()
        {
            Application.runInBackground = true;
            StartCoroutine(PlayVideo());
        }
    
  9. 在 Start() 方法之後,插入 PlayVideo() IEnumerator 方法,此方法將用來順暢地啟動影片(因此不會看到任何口水)。

        private IEnumerator PlayVideo()
        {
            // create a new render texture to display the video 
            videoStreamRenderTexture = new RenderTexture(2160, 1440, 32, RenderTextureFormat.ARGB32);
    
            videoStreamRenderTexture.Create();
    
            // assign the render texture to the object material 
            Material sphereMaterial = sphere.GetComponent<Renderer>().sharedMaterial;
    
            //create a VideoPlayer component 
            videoPlayer = gameObject.AddComponent<VideoPlayer>();
    
            // Set the video to loop. 
            videoPlayer.isLooping = true;
    
            // Set the VideoPlayer component to play the video from the texture 
            videoPlayer.renderMode = VideoRenderMode.RenderTexture;
    
            videoPlayer.targetTexture = videoStreamRenderTexture;
    
            // Add AudioSource 
            audioSource = gameObject.AddComponent<AudioSource>();
    
            // Pause Audio play on Awake 
            audioSource.playOnAwake = true;
            audioSource.Pause();
    
            // Set Audio Output to AudioSource 
            videoPlayer.audioOutputMode = VideoAudioOutputMode.AudioSource;
            videoPlayer.source = VideoSource.Url;
    
            // Assign the Audio from Video to AudioSource to be played 
            videoPlayer.EnableAudioTrack(0, true);
            videoPlayer.SetTargetAudioSource(0, audioSource);
    
            // Assign the video Url depending on the current scene 
            switch (SceneManager.GetActiveScene().name)
            {
                case "VideoScene1":
                    videoPlayer.url = video1endpoint;
                    break;
    
                case "VideoScene2":
                    videoPlayer.url = video2endpoint;
                    break;
    
                default:
                    break;
            }
    
            //Set video To Play then prepare Audio to prevent Buffering 
            videoPlayer.Prepare();
    
            while (!videoPlayer.isPrepared)
            {
                yield return null;
            }
    
            sphereMaterial.mainTexture = videoStreamRenderTexture;
    
            //Play Video 
            videoPlayer.Play();
    
            //Play Sound 
            audioSource.Play();
    
            while (videoPlayer.isPlaying)
            {
                yield return null;
            }
        }
    
  10. 這個類別 所需的最後一個方法是 ChangeScene() 方法,用來在場景之間交換。

        public void ChangeScene()
        {
            SceneManager.LoadScene(SceneManager.GetActiveScene().name == "VideoScene1" ? "VideoScene2" : "VideoScene1");
        }
    

    提示

    ChangeScene() 方法會使用稱為條件運算子的方便 C# 功能。 這可讓條件進行檢查,然後根據檢查結果傳回的值,全都在單一語句內。 請遵循此 連結以深入瞭解條件運算符

  11. 在 Visual Studio 中儲存變更,再返回 Unity。

  12. 回到 Unity 編輯器中,按兩下 [VideoController] 類別 [from]{.underline} 將 Scripts 資料夾拖曳階層面板中的主相機物件

  13. 按兩下 [主要相機 ] 並查看 [偵測器面板]。 您會注意到,在新增的腳本元件內,有一個字段具有空白值。 這是參考欄位,其以程式代碼內的公用變數為目標。

  14. InsideOutSphere 對象從 階層面板 拖曳至 Sphere 位置,如下圖所示。

    階層功能表的螢幕快照。選取主要相機。Sphere 位置的螢幕快照。

第 6 章 - 建立 Gaze 類別

此類別負責建立將投射自 Main Camera 的 Raycast,以偵測使用者正在查看的物件。 在此情況下, Raycast 必須識別使用者是否正在查看 場景中的 GazeButton 物件,並觸發行為。

若要建立此類別:

  1. 移至您先前建立的 Scripts 資料夾。

  2. 滑鼠右鍵按兩下 [項目面板],[建立C# 腳本]。 將腳本 命名為 Gaze

  3. 按兩下新的 Gaze 腳本,以使用 Visual Studio 2017 開啟它。

  4. 請確定下列命名空間位於文稿頂端,並移除任何其他命名空間:

    using UnityEngine;
    
  5. 然後在 Gaze 類別內新增下列變數:

        /// <summary> 
        /// Provides Singleton-like behaviour to this class. 
        /// </summary> 
        public static Gaze instance;
    
        /// <summary> 
        /// Provides a reference to the object the user is currently looking at. 
        /// </summary> 
        public GameObject FocusedGameObject { get; private set; }
    
        /// <summary> 
        /// Provides a reference to compare whether the user is still looking at 
        /// the same object (and has not looked away). 
        /// </summary> 
        private GameObject oldFocusedObject = null;
    
        /// <summary> 
        /// Max Ray Distance 
        /// </summary> 
        float gazeMaxDistance = 300;
    
        /// <summary> 
        /// Provides whether an object has been successfully hit by the raycast. 
        /// </summary> 
        public bool Hit { get; private set; }
    
  6. 現在必須新增 Awake()Start() 方法的程式代碼。

        private void Awake()
        {
            // Set this class to behave similar to singleton 
            instance = this;
        }
    
        void Start()
        {
            FocusedGameObject = null;
        }
    
  7. 在 Update() 方法中新增下列程式代碼,以投影 Raycast 並偵測目標命中:

        void Update()
        {
            // Set the old focused gameobject. 
            oldFocusedObject = FocusedGameObject;
            RaycastHit hitInfo;
    
            // Initialise Raycasting. 
            Hit = Physics.Raycast(Camera.main.transform.position, Camera.main.transform.forward, out hitInfo, gazeMaxDistance);
    
            // Check whether raycast has hit. 
            if (Hit == true)
            {
                // Check whether the hit has a collider. 
                if (hitInfo.collider != null)
                {
                    // Set the focused object with what the user just looked at. 
                    FocusedGameObject = hitInfo.collider.gameObject;
                }
                else
                {
                    // Object looked on is not valid, set focused gameobject to null. 
                    FocusedGameObject = null;
                }
            }
            else
            {
                // No object looked upon, set focused gameobject to null.
                FocusedGameObject = null;
            }
    
            // Check whether the previous focused object is this same 
            // object (so to stop spamming of function). 
            if (FocusedGameObject != oldFocusedObject)
            {
                // Compare whether the new Focused Object has the desired tag we set previously. 
                if (FocusedGameObject.CompareTag("GazeButton"))
                {
                    FocusedGameObject.SetActive(false);
                    VideoController.instance.ChangeScene();
                }
            }
        }
    
  8. 在 Visual Studio 中儲存變更,再返回 Unity。

  9. 按兩下 [注視] 類別,然後將 [腳稿] 資料夾拖曳至 [階層面板] 中的 [主要相機] 物件。

第 7 章 - 設定兩個 Unity 場景

本章的目的是要設定兩個場景,每個場景都裝載視訊進行串流。 您將複製您已建立的場景,因此您不需要再次設定它,不過您接著會編輯新的場景,讓 GazeButton 物件位於不同的位置,而且外觀不同。 這是要示範如何在場景之間變更。

  1. 若要這樣做,請移至 [ 將 > 場景儲存為...]。隨即會出現儲存視窗。 按兩下 [ 新增資料夾] 按鈕。

    第 7 章 - 設定兩個 Unity 場景

  2. 將資料夾 命名為 Scenes

  3. [儲存 場景 ] 視窗仍會開啟。 開啟新建立 的 Scenes 資料夾。

  4. 在 [ 檔名: 文字] 字段中,輸入 VideoScene1,然後按 [ 儲存]。

  5. 回到 Unity,開啟您的 Scenes 資料夾,然後以滑鼠左鍵按兩下 VideoScene1 檔案。 使用鍵盤,然後按 Ctrl + D ,您將複製該場景

    提示

    您也可以巡覽至 [編輯>重複] 來執行重複命令。

  6. Unity 會自動遞增場景名稱編號,但無論如何檢查,以確保它符合先前插入的程序代碼。

    您應該有 VideoScene1VideoScene2

  7. 使用您的兩個場景,移至 [ 檔案 > 建置設定]。 開啟 [建置設定] 視窗后,將場景拖曳至 [建置] 區段中的 [場景]。

    [建置設定] 視窗的螢幕快照。

    提示

    您可以從 [場景] 資料夾中選取這兩個場景,方法是按住 Ctrl 按鈕,然後按兩下滑鼠左鍵,最後拖曳兩者。

  8. 關閉 [ 建置設定] 視窗,然後按兩下 VideoScene2

  9. 在第二個場景開啟時,按兩下 InsideOutSphereGazeButton 子物件,並將其轉換設定如下:

轉換 - 位置

X Y Z
0 1.3 3.6

轉換 - 旋轉

X Y Z
0 0 0

轉換 - 調整

X Y Z
1 1 1
  1. 在仍然選取 GazeButton 子系時,請查看 InspectorMesh 篩選 點選單擊 [網格參考] 欄位旁的小目標:

    [注視] 按鈕的偵測器畫面螢幕快照。

  2. [選取網格] 彈出視窗隨即出現。 按兩下 [資產] 清單中的 Cube 網格。

    [選取網格] 彈出視窗的螢幕快照。

  3. 網格篩選將會更新,現在會更新為 Cube。 現在,按兩下Sphere碰撞器旁的齒輪圖示,然後按兩下 [移除元件],從這個物件中刪除碰撞器。

    Sphere 碰撞器功能表的螢幕快照。已選取 [移除元件]。

  4. 在仍然選取 GazeButton 之後,按兩下 Inspector 底部的 [新增元件] 按鈕。 在搜尋欄位中,輸入方塊和 Box Collider 將會是一個選項,請按兩下此選項,將 Box Collider 新增您的 GazeButton 物件。

    [新增元件] 搜尋方塊的螢幕快照。

  5. GazeButton 現在已部分更新,看起來不同,不過,您現在會建立新的Material,使其看起來完全不同,而且更容易辨識為不同的物件,而不是第一個場景中的物件。

  6. 流覽至 [項目面板] 內的 [材質] 資料夾。 複製 ButtonMaterial 材質 (按鍵盤上的 Ctrl + D,或以滑鼠左鍵按兩下 [材質],然後從 [編輯檔案] 選單選項選取 [重複]。

    [專案] 索引標籤中 [材質] 資料夾的螢幕快照。已選取重複的編輯功能表螢幕快照。

  7. 選取新的 ButtonMaterial Material (這裡命名為 ButtonMaterial 1),然後在 Inspector按兩下 [Albedo 色彩] 視窗。 彈出視窗隨即出現,您可以在其中選取另一種色彩(選擇您想要的色彩),然後關閉快顯。 Material 會是它自己的實例,而且與原始實例不同。

    色彩選取彈出視窗的螢幕快照。

  8. 將新 材質 拖曳到 GazeButton 子系,以立即完全更新其外觀,以便輕鬆地與第一個場景按鈕區別。

    專案編輯器場景索引標籤的螢幕快照。

  9. 此時,您可以在 [編輯器] 中測試專案,再建置 UWP 專案。

    • 按下編輯器中的 [播放] 按鈕,並戴上耳機。

      顯示播放、暫停和略過按鈕的螢幕快照。播放按鈕會反白顯示。

  10. 查看兩 個 GazeButton 物件,以在第一個和第二個視訊之間切換。

第 8 章 - 建置 UWP 解決方案

一旦確定編輯器沒有錯誤,您就可以開始建置。

若要建置:

  1. 按兩下 [檔案>儲存] 以儲存目前的場景。

  2. 核取名為 Unity C# 專案的 方塊(這很重要,因為它可讓您在建置完成後編輯類別)。

  3. 移至 [ 檔案 > 建置設定],按兩下 [ 置]。

  4. 系統會提示您選取您要建置解決方案的資料夾。

  5. 建立 BUILDS 資料夾,並在該資料夾中建立另一個具有所選適當名稱的資料夾。

  6. 按兩下新的資料夾,然後按兩下 [ 選取資料夾],以便選擇該資料夾,以在該位置開始建置。

    醒目提示 BUILDS 資料夾的螢幕快照。醒目提示 [視訊串流建置] 資料夾的螢幕快照。

  7. Unity 完成建置後(可能需要一些時間),它會在組建的位置開啟 檔案總管 視窗。

第 9 章 - 在本機計算機上部署

建置完成後,檔案總管 視窗會出現在組建的位置。 開啟您命名並建置至的資料夾,然後按兩下該資料夾中的方案 (.sln) 檔案,以使用Visual Studio 2017 開啟您的方案。

唯一要做的就是將您的應用程式部署到您的電腦(或 本機計算機)。

若要部署至本機電腦:

  1. Visual Studio 2017 中,開啟剛建立的方案檔案。

  2. 在 [解決方案平臺] 中,選取 [x86] [本機計算機]。

  3. 在 [解決方案組態] 中,選取 [偵錯]。

    [方案組態] 功能表的螢幕快照。

  4. 您現在必須將任何套件還原到您的解決方案。 以滑鼠右鍵按下您的 方案,然後按兩下 [ 還原解決方案的 NuGet 套件...]

    注意

    這樣做是因為 Unity 建置的套件需要以目標方式搭配本機計算機參考使用。

  5. 移至 [ 建置] 功能表 ,然後按下 [ 部署方案 ] 將應用程式側載至您的電腦。 Visual Studio 會先建置,然後部署您的應用程式。

  6. 您的應用程式現在應該會出現在已安裝的應用程式清單中,準備好啟動。

    已安裝應用程式清單的螢幕快照。

當您執行混合實境應用程式時,您會位於 應用程式內所使用的 InsideOutSphere 模型內。 這個球體將是視頻將被串流到的地方,提供360度的視線,傳入的視頻(這是為這種視角拍攝)。 如果視訊需要幾秒鐘才能載入,則不要感到驚訝,您的應用程式受限於可用的因特網速度,因為影片需要擷取,然後下載,以便串流到您的應用程式。 當您準備好時,請變更場景並開啟您的第二個視訊,方法是凝視紅色球體! 然後隨意返回,在第二個場景中使用藍色立方體!

您已完成的 Azure 媒體服務應用程式

恭喜,您建置了混合實境應用程式,利用 Azure 媒體服務串流 360 個影片。

範例混合實境應用程式的螢幕快照。

混合實境應用程式範例的螢幕快照。

Bonus 練習

練習 1

完全可以使用單一場景來變更本教學課程中的影片。 實驗您的應用程式,並將其變成單一場景! 也許甚至將另一個視頻新增至混合。

練習 2

試驗 Azure 和 Unity,並嘗試實作應用程式自動選取不同檔案大小的視訊的能力,視因特網聯機的強度而定。