Created
August 1, 2022 01:28
-
-
Save aki-lua87/4fe8ddb88aaddc643db8f57e67be4bc4 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 HoshinoLabs.IwaSync3; | |
using UdonSharpEditor; | |
using UnityEditor; | |
using UnityEngine; | |
using UnityEngine.UI; | |
using VRC.Udon; | |
namespace aki_lua87.Editor.iwaSyncPlaylist | |
{ | |
public class iwaSyncPlaylistEditor : EditorWindow | |
{ | |
private readonly string logPrefix = "[aki_lua87] "; | |
[SerializeField] private GameObject playList; | |
[SerializeField] private string channelID = ""; | |
[SerializeField] private string urlprefix = ""; | |
[SerializeField] private bool isLiveInsert = false; | |
[MenuItem("Tools/aki_lua87/iwaSyncPlaylistEditor")] | |
private static void Init() | |
{ | |
EditorWindow.GetWindow(typeof(iwaSyncPlaylistEditor)); | |
} | |
private void OnGUI() | |
{ | |
using (new GUILayout.VerticalScope()) | |
{ | |
EditorGUILayout.Space(); | |
this.playList = (GameObject)EditorGUILayout.ObjectField("iwaSync3 PlayList", this.playList, typeof(GameObject), true); | |
this.urlprefix = EditorGUILayout.TextField("URLプレフィックス", this.urlprefix); | |
EditorGUILayout.Space(); | |
this.channelID = EditorGUILayout.TextField("YoutubeチャンネルID", this.channelID); | |
EditorGUILayout.Space(); | |
if (GUILayout.Button("現在の最新15動画を追加")) | |
{ | |
CreatePlaylistForYoutubeChannel(); | |
} | |
this.isLiveInsert = EditorGUILayout.Toggle("ライブを含めるか(β)", this.isLiveInsert); | |
if (GUILayout.Button("チャンネルを追加(β)")) | |
{ | |
CreatePlaylistForAkiSyatem(); | |
} | |
} | |
} | |
[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 tracks = new List<Track>(); | |
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 track = new Track | |
{ | |
title = $"{videoTitle}", | |
url = targetURL | |
}; | |
tracks.Add(track); | |
} | |
CreatePlaylist(auther.Value, tracks); | |
} | |
} | |
catch (Exception e) | |
{ | |
Debug.Log($"{logPrefix}プレイリスト作成に失敗しました: {e.Message}"); | |
} | |
return; | |
} | |
public async void CreatePlaylistForAkiSyatem() | |
{ | |
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 urlleft = $"{urlprefix}https://vrc.akakitune87.net/videos/yt/ch/{channel}?n="; | |
var tagTitle = "" + resData.auther; | |
var liveURL = $"{urlprefix}https://vrc.akakitune87.net/videos/ytlive/ch/{channel}"; | |
var tracks = new List<Track>(); | |
var track = new Track | |
{ | |
title = $"目次", | |
url = indexURL | |
}; | |
tracks.Add(track); | |
if (isLiveInsert) | |
{ | |
var track2 = new Track | |
{ | |
title = $"LIVE", | |
url = liveURL, | |
mode = TrackMode.Live | |
}; | |
tracks.Add(track2); | |
} | |
for (int i = 0; i < 20; i++) | |
{ | |
var targetURL = $"{urlleft}{i}"; | |
track = new Track | |
{ | |
title = $"{i + 1}", | |
url = targetURL | |
}; | |
tracks.Add(track); | |
} | |
CreatePlaylist(tagTitle, tracks); | |
} | |
catch (Exception e) | |
{ | |
Debug.Log($"{logPrefix}プレイリスト作成に失敗しました: {e}"); | |
} | |
} | |
private void CreatePlaylist(string tagTitle, List<Track> tracks) | |
{ | |
// プレイリスト中身 | |
var serializedProperty = this.playList.GetComponent<Playlist>(); | |
var serializedObject = new SerializedObject(serializedProperty); | |
var tracksProperty = serializedObject.FindProperty("tracks"); | |
tracksProperty.arraySize = tracks.Count; | |
// プレイリストのタイトル | |
var tittle = this.playList.transform.Find("Udon (Playlist)/Canvas/Panel/Header/Version/Text").gameObject; | |
var titleText = tittle.GetComponent<Text>(); | |
titleText.text = tagTitle; | |
for (var i = 0; i < tracksProperty.arraySize; i++) | |
{ | |
var trackProperty = tracksProperty.GetArrayElementAtIndex(i); | |
trackProperty.FindPropertyRelative("title").stringValue = tracks[i].title; | |
trackProperty.FindPropertyRelative("url").stringValue = tracks[i].url; | |
} | |
if (playList) | |
{ | |
serializedObject.ApplyModifiedProperties(); | |
} | |
} | |
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