OSDN Git Service

YouTubeのサムネイルを表示するURLのパターンを追加
authorKimura Youichi <kim.upsilon@bucyou.net>
Tue, 25 Jan 2022 16:59:29 +0000 (01:59 +0900)
committerKimura Youichi <kim.upsilon@bucyou.net>
Tue, 25 Jan 2022 16:59:29 +0000 (01:59 +0900)
OpenTween.Tests/Thumbnail/Services/YoutubeTest.cs [new file with mode: 0644]
OpenTween/Resources/ChangeLog.txt
OpenTween/Thumbnail/Services/Youtube.cs

diff --git a/OpenTween.Tests/Thumbnail/Services/YoutubeTest.cs b/OpenTween.Tests/Thumbnail/Services/YoutubeTest.cs
new file mode 100644 (file)
index 0000000..3d39b7a
--- /dev/null
@@ -0,0 +1,44 @@
+// OpenTween - Client of Twitter
+// Copyright (c) 2022 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
+// All rights reserved.
+//
+// This file is part of OpenTween.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License
+// for more details.
+//
+// You should have received a copy of the GNU General public License along
+// with this program. If not, see <http://www.gnu.org/licenses/>, or write to
+// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace OpenTween.Thumbnail.Services
+{
+    public class YoutubeTest
+    {
+        [Theory]
+        [InlineData("https://www.youtube.com/watch?v=aaaaa", "aaaaa")]
+        [InlineData("https://www.youtube.com/watch?v=aaaaa#hoge", "aaaaa")]
+        [InlineData("https://www.youtube.com/watch?feature=youtu.be&v=aaaaa&app=desktop", "aaaaa")]
+        [InlineData("https://m.youtube.com/watch?v=aaaaa", "aaaaa")]
+        [InlineData("https://youtu.be/aaaaa", "aaaaa")]
+        [InlineData("https://youtu.be/aaaaa?t=123", "aaaaa")]
+        [InlineData("https://www.youtube.com/channel/aaaaa", null)] // チャンネルページ
+        public void GetVideoIdFromUrl_Test(string testUrl, string expected)
+            => Assert.Equal(expected, Youtube.GetVideoIdFromUrl(testUrl));
+    }
+}
index 6bc611b..05bdf5d 100644 (file)
@@ -2,7 +2,7 @@
 
 ==== Ver 2.4.4-dev(2019/xx/xx)
  * CHG: pic.twitter.com の画像URLのフォーマット変更に対応
- * CHG: Instagramのサムネイルを表示するURLのパターンを追加
+ * CHG: Instagram, Youtubeのサムネイルを表示するURLのパターンを追加
  * FIX: DMの添付画像をブラウザで開く場合に使用するURLを変更
  * FIX: 大文字アルファベットを含むハッシュタグがユーザー情報画面で正しくリンク化されない不具合を修正 (thx @naminodarie!)
 
index 181f8a5..88cc6e2 100644 (file)
@@ -30,10 +30,11 @@ using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
+using System.Text.RegularExpressions;
 using System.Threading;
 using System.Threading.Tasks;
+using System.Web;
 using System.Xml;
-using System.Text.RegularExpressions;
 using OpenTween.Models;
 
 namespace OpenTween.Thumbnail.Services
@@ -41,17 +42,16 @@ namespace OpenTween.Thumbnail.Services
     class Youtube : IThumbnailService
     {
         public static readonly Regex UrlPatternRegex =
-            new Regex(@"^https?://(?:((?:www|m)\.youtube\.com)|(youtu\.be))/(watch\?v=)?(?<videoid>([\w\-]+))");
+            new Regex(@"^https?://(?:www\.youtube\.com|m\.youtube\.com|youtu\.be)/");
 
         public override Task<ThumbnailInfo?> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
         {
             return Task.Run(() =>
             {
-                var match = Youtube.UrlPatternRegex.Match(url);
-                if (!match.Success)
+                var videoId = Youtube.GetVideoIdFromUrl(url);
+                if (videoId == null)
                     return null;
 
-                var videoId = match.Groups["videoid"].Value;
                 var imgUrl = "https://i.ytimg.com/vi/" + videoId + "/hqdefault.jpg";
 
                 return new ThumbnailInfo
@@ -63,5 +63,29 @@ namespace OpenTween.Thumbnail.Services
                 };
             }, token);
         }
+
+        public static string? GetVideoIdFromUrl(string urlStr)
+        {
+            if (!Youtube.UrlPatternRegex.IsMatch(urlStr))
+                return null;
+
+            var url = new Uri(urlStr);
+            switch (url.Host)
+            {
+                case "www.youtube.com":
+                case "m.youtube.com":
+                    {
+                        if (url.AbsolutePath != "/watch")
+                            return null;
+
+                        var query = HttpUtility.ParseQueryString(url.Query);
+                        return query["v"];
+                    }
+                case "youtu.be":
+                    return url.AbsolutePath.Substring(1);
+                default:
+                    return null;
+            }
+        }
     }
 }