😺
UnityでYoutubeの動画をリンクから再生してやる
UnityでYoutubeのリンクから動画を再生したくなるときはありませんか?私はあります。
ちょっと調べたところいい感じの実装方法があったので一種の備忘録として残しておきます。
先駆者としては上のリンクの物がありますがなんかできなかったのでYoutube Explodeを用いて動画プレイヤーを実装しました。Youtube Explodeの導入
Youtube Explode自体はこれです。ですがUPMに対応していなくて面倒くさいというかそもそもInstall方がNuGet経由なのでNuGetForUnityを導入してしまいましょう。 導入法に関してはNuGetForUnityのHow Do I install NuGetForUnityを読んでください。
軽いセットアップ
NuGetForUnityを導入できたらFileやらWindowが並んでるところにNuGetが生成されているのでそこをクリックしManage NuGet Packagesをクリックし、youtubeと打ち込むとYoutube Explodeがあるのでインストールしてください
実装
これでNuGetとYoutube Explodeが導入できたので実装していきましょう。
using UnityEngine;
using UnityEngine.Video;
using UnityEngine.UI;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using YoutubeExplode;
using YoutubeExplode.Videos.Streams;
using TMPro;
public class PlayYoutubeVideo : MonoBehaviour
{
[SerializeField] GameObject buttonPrefab; // ボタンのプレハブ
[SerializeField] Transform contentTransform; // ContentのTransform
[SerializeField] string[] urls; // 動画のURL配列
[SerializeField] string[] Discription;
private VideoPlayer videoPlayer;
private int currentVideoIndex = 0;
void Start()
{
videoPlayer = GetComponent<VideoPlayer>();
CreatePlaylistButtons(); // プレイリストのボタンを作成
}
private void CreatePlaylistButtons()
{
for (int i = 0; i < urls.Length; i++)
{
string url = urls[i];
CreateButton(url, i + 1); // ボタンを作成
}
}
private void CreateButton(string url, int index)
{
GameObject newbutton = Instantiate(buttonPrefab, contentTransform); // ボタンを生成
if(Discription[index-1] == null){
newbutton.GetComponentInChildren<TMP_Text>().text = "Play Video " + index; // 通し番号を付ける
}else{
newbutton.GetComponentInChildren<TMP_Text>().text = Discription[index-1]; // 動画のタイトル概要をつける。Discriptionが空なら上の通し番号を
}
newbutton.GetComponent<Button>().onClick.AddListener(() => PlayYoutubeVideos(url)); // ボタンがクリックされたときのリスナーを追加
}
public async void PlayYoutubeVideos(string url)
{
var youtube = new YoutubeClient();
var videoId = ExtractVideoId(url);
if (string.IsNullOrEmpty(videoId))
{
Debug.LogError("Invalid YouTube URL");
return;
}
var streamManifest = await youtube.Videos.Streams.GetManifestAsync(videoId);
var streamInfo = streamManifest.GetMuxedStreams().GetWithHighestVideoQuality();
if (streamInfo != null)
{
videoPlayer.url = streamInfo.Url;
videoPlayer.Play();
}
}
public void PauseVideo()
{
if (videoPlayer.isPlaying)
{
videoPlayer.Pause();
}
}
public void StopVideo()
{
if (videoPlayer.isPlaying)
{
videoPlayer.Stop();
}
}
public void SaiseiVideo()
{
if (!videoPlayer.isPlaying)
{
videoPlayer.Play();
}
}
public void NextVideo()
{
currentVideoIndex = (currentVideoIndex + 1) % urls.Length;
PlayYoutubeVideos(urls[currentVideoIndex]);
}
public void PreviousVideo()
{
currentVideoIndex = (currentVideoIndex - 1 + urls.Length) % urls.Length;
PlayYoutubeVideos(urls[currentVideoIndex]);
}
private string ExtractVideoId(string url)
{
var regex = new Regex(@"(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^""&?\/\s]{11})", RegexOptions.IgnoreCase);
var match = regex.Match(url);
return match.Success ? match.Groups[1].Value : null;
}
}
やってることと言えば[SerializeField]でURLを読み込んでやってその要素数をベースにボタンも生成していると言うだけです。本来だったらInputFieldから読んであげた方が嬉しいんでしょうがVR用に仮で作っている都合上VRのキーボードで入力やらコピペをするのは面倒くさいですし費用対効果に見合わないのでSerializeFieldに文字列を突っ込む形にしています。
2Dゲームとか3Dゲームならば入力の箇所をInputFieldにでもしてあげてください。
あとはURLをいい感じに正規表現で加工してあげてビデオIDを抜いているだけです。
PauseやSaiseiなどに関してもそれを振りたいボタンに振ってあげれば再生や一時停止、次の動画などの処理ができるはずです。
以上ですお疲れ様でした
Discussion