Created
August 1, 2022 01:19
-
-
Save aki-lua87/3abfa67b4769f545cad1deb633593ca7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Linq; | |
using System.Net.Http; | |
using System.Text; | |
using System.Xml.Linq; | |
using Kinel.VideoPlayer.Scripts; | |
using Kinel.VideoPlayer.Scripts.Parameter; | |
using Kinel.VideoPlayer.Udon; | |
using Kinel.VideoPlayer.Udon.Playlist; | |
using UdonSharpEditor; | |
using UnityEditor; | |
using UnityEngine; | |
using UnityEngine.UI; | |
using VRC.Udon; | |
namespace aki_lua87.Editor.KineLPlaylist | |
{ | |
public class KineLPlaylistV2Editor : EditorWindow | |
{ | |
private readonly string logPrefix = "[aki_lua87] "; | |
[SerializeField] private GameObject playList; | |
[SerializeField] private string channelID = ""; | |
[SerializeField] private string searchWord = ""; | |
[SerializeField] private string urlprefix = ""; | |
[SerializeField] private bool isLiveInsert = false; | |
[SerializeField] private bool isDynamicLink = true; | |
private KinelPlaylistScript _playlist; | |
[MenuItem("Tools/aki_lua87/KineLPlaylistV2Editor")] | |
private static void Init() | |
{ | |
EditorWindow.GetWindow(typeof(KineLPlaylistV2Editor)); | |
} | |
private void OnGUI() | |
{ | |
using (new GUILayout.VerticalScope()) | |
{ | |
EditorGUILayout.Space(); | |
this.playList = (GameObject)EditorGUILayout.ObjectField("KineLPlaylist", this.playList, typeof(GameObject), true); | |
this.urlprefix = EditorGUILayout.TextField("URLプレフィックス", this.urlprefix); | |
EditorGUILayout.Space(); | |
this.channelID = EditorGUILayout.TextField("YoutubeチャンネルID", this.channelID); | |
EditorGUILayout.Space(); | |
this.isDynamicLink = EditorGUILayout.Toggle("動的URLを発行するか", this.isDynamicLink); | |
if(this.isDynamicLink) | |
this.isLiveInsert = EditorGUILayout.Toggle("ライブを含めるか(β)", this.isLiveInsert); | |
else | |
EditorGUILayout.Space(); | |
if (GUILayout.Button("プレイリスト追加")) | |
{ | |
if(this.isDynamicLink) | |
{ | |
CreatePlaylistForAkiSyatemC(); | |
}else{ | |
CreatePlaylistForYoutubeChannel(); | |
} | |
} | |
EditorGUILayout.Space(); | |
EditorGUILayout.Space(); | |
this.searchWord = EditorGUILayout.TextField("検索ワード", this.searchWord); | |
using (new GUILayout.HorizontalScope()) | |
{ | |
if (GUILayout.Button("検索ワードで追加")) | |
{ | |
CreatePlaylistForAkiSyatemQ(this.searchWord); | |
} | |
} | |
EditorGUILayout.Space(); | |
GUILayout.Label("※追加後にGanelate playlistの押下を忘れないこと"); | |
} | |
} | |
[Serializable] | |
public class akiWebResponse | |
{ | |
public string result; | |
public string auther; | |
} | |
public void CreatePlaylistForYoutubeChannel() | |
{ | |
Debug.Log($"{logPrefix}Call CreatePlaylistForYoutubeChannel"); | |
try | |
{ | |
var channel = extractChannelID(channelID); | |
string URL = $"https://www.youtube.com/feeds/videos.xml?channel_id={channel}"; | |
var xml = XDocument.Load(URL); | |
var root = xml.Root; | |
var auther = root.Elements().Where(p => p.Name.LocalName == "title").FirstOrDefault(); | |
Debug.Log($"{logPrefix}auther => " + auther.Value); | |
var entrys = root.Elements().Where(p => p.Name.LocalName == "entry"); | |
if (entrys != null) | |
{ | |
var videoDatas = new List<VideoData>(); | |
foreach (var entry in entrys) | |
{ | |
var mediaGroup = entry.Elements().Where(p => p.Name.LocalName == "group").FirstOrDefault(); | |
var videoTitle = mediaGroup.Elements().Where(p => p.Name.LocalName == "title").Select(p => p.Value).FirstOrDefault(); | |
var description = mediaGroup.Elements().Where(p => p.Name.LocalName == "description").Select(p => p.Value).FirstOrDefault(); | |
var url = entry.Elements().Where(p => p.Name.LocalName == "link").Select(p => p.Attribute("href").Value).FirstOrDefault(); | |
Debug.Log($"videoTitle:{videoTitle} description:{description} url:{url}"); | |
var targetURL = $"{urlprefix}{url}"; | |
var videoData = new VideoData | |
{ | |
title = $"{videoTitle}", | |
url = targetURL, | |
description = $"", | |
mode = 0 | |
}; | |
videoDatas.Add(videoData); | |
} | |
CreatePlaylist(auther.Value, videoDatas); | |
} | |
} | |
catch (Exception e) | |
{ | |
Debug.Log($"{logPrefix}プレイリスト作成に失敗しました: {e.Message}"); | |
} | |
return; | |
} | |
public async void CreatePlaylistForAkiSyatemC() | |
{ | |
Debug.Log($"{logPrefix}Call CreatePlaylistForAkiSyatem"); | |
try | |
{ | |
var channel = extractChannelID(channelID); | |
string URL = $"https://vrc.akakitune87.net/video/yt/channel/regist"; | |
// TODO: 手書きじゃないいい方法 | |
var reqJson = "{ \"channel_id\" : \"" + channel + "\"}"; | |
var content = new StringContent(reqJson, Encoding.UTF8, "application/json"); | |
var client = new System.Net.Http.HttpClient(); | |
var res = await client.PostAsync(URL, content); | |
var resJson = await res.Content.ReadAsStringAsync(); | |
Debug.Log($"{logPrefix}response json:" + resJson); | |
var resData = JsonUtility.FromJson<akiWebResponse>(resJson); | |
Debug.Log($"{logPrefix}data:" + JsonUtility.ToJson(resData)); | |
if (!(resData.result == "OK")) | |
{ | |
Debug.Log($"{logPrefix}API実行に失敗しました"); | |
return; | |
} | |
var indexURL = $"{urlprefix}https://vrc.akakitune87.net/videos/yt/chlist/{channel}"; | |
var liveURL = $"{urlprefix}https://vrc.akakitune87.net/videos/ytlive/ch/{channel}"; | |
var urlleft = $"{urlprefix}https://vrc.akakitune87.net/videos/yt/ch/{channel}?n="; | |
var tagTitle = "" + resData.auther; | |
var videoDatas = new List<VideoData>(); | |
var videoData = new VideoData | |
{ | |
title = $"目次", | |
url = indexURL, | |
description = $"", | |
mode = 0 | |
}; | |
videoDatas.Add(videoData); | |
if (isLiveInsert) | |
{ | |
var liveData = new VideoData | |
{ | |
title = $"LIVE", | |
url = liveURL, | |
description = $"", | |
mode = 1 | |
}; | |
videoDatas.Add(liveData); | |
} | |
for (int i = 0; i < 20; i++) | |
{ | |
var targetURL = $"{urlleft}{i}"; | |
videoData = new VideoData | |
{ | |
title = $"{i + 1}", | |
url = targetURL, | |
description = $"", | |
mode = 0 | |
}; | |
videoDatas.Add(videoData); | |
} | |
CreatePlaylist(tagTitle, videoDatas); | |
} | |
catch (Exception e) | |
{ | |
Debug.Log($"{logPrefix}プレイリスト作成に失敗しました: {e}"); | |
} | |
} | |
public void CreatePlaylist(string tagTitle, List<VideoData> videoDatas) | |
{ | |
// Video listにURLを挿入 | |
var serializedProperty = this.playList.GetComponent<KinelPlaylistScript>(); | |
var serializedObject = new SerializedObject(serializedProperty); | |
var videoDatasProperty = serializedObject.FindProperty("videoDatas"); | |
videoDatasProperty.arraySize = videoDatas.Count; | |
// タグに名前を挿入 | |
// 未実装、というかもっと上のレイヤで実装 | |
for (var i = 0; i < videoDatasProperty.arraySize; i++) | |
{ | |
var videoDataProperty = videoDatasProperty.GetArrayElementAtIndex(i); | |
videoDataProperty.FindPropertyRelative("title").stringValue = videoDatas[i].title; | |
videoDataProperty.FindPropertyRelative("url").stringValue = videoDatas[i].url; | |
} | |
if (playList) | |
{ | |
serializedObject.ApplyModifiedProperties(); | |
} | |
} | |
public async void CreatePlaylistForAkiSyatemQ(string q) | |
{ | |
Debug.Log($"{logPrefix}Call CreatePlaylistForAkiSyatemQ"); | |
try | |
{ | |
var urlleft = $"{urlprefix}https://vrc.akakitune87.net/videos/yt/query?q={q}&n="; | |
var videoDatas = new List<VideoData>(); | |
for (int i = 0; i < 20; i++) | |
{ | |
var targetURL = $"{urlleft}{i}"; | |
var videoData = new VideoData | |
{ | |
title = $"{i + 1}", | |
url = targetURL, | |
description = $"", | |
mode = 0 | |
}; | |
videoDatas.Add(videoData); | |
} | |
CreatePlaylist("", videoDatas); | |
} | |
catch (Exception e) | |
{ | |
Debug.Log($"{logPrefix}プレイリスト作成に失敗しました: {e}"); | |
} | |
} | |
private string extractChannelID(string str) | |
{ | |
if (str.Contains("https://www.youtube.com/channel/")) | |
{ | |
Debug.Log($"{logPrefix} 想定外の引数: 抽出処理を実施 {str}"); | |
return str.Replace("https://www.youtube.com/channel/", ""); | |
} | |
return str; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment