【问题标题】:Show Twitch.tv stream within a unity3D application在 unity3D 应用程序中显示 Twitch.tv 流
【发布时间】:2016-01-18 14:39:29
【问题描述】:

我想制作一个 Unity3D 应用程序,可以在其中观看当前的 Twitch.tv 直播。

我不确定这是否可行,例如,使用 twitch api (https://github.com/justintv/twitch-api)

我了解 Unity3D 中的视频纹理,并且知道如何使用默认的 twitch api 基础知识,但我不知道如何将正在运行的 twitch 流集成到我的应用程序中。

如果可能的话,有人可以给我一个提示吗?

非常感谢和最好的问候 梅芙

【问题讨论】:

    标签: unity3d video-streaming twitch


    【解决方案1】:

    来自 twitch 的流最终是 MPEG-4 (H264/M3U)。因此,如果您可以在 Unity 中渲染它,那么您就可以渲染 twitch 流。

    有几个步骤可以从 twitch 获取正确的 URL,并且会随着时间的推移而改变。您必须在播放流时检查当前的 twitch 页面,以查看 javascript 如何构建请求(网址和标头)。

    最后,javascript 将构建一个访问令牌,然后使用它从其中一个 twitch 边缘服务器请求一个名为 index-live.m3u8 的文件。该文件包含直播流最后几秒的文件名列表(以及一些其他元数据)。它看起来像这样

    https://video-edge-c61b44.lax01.hls.ttvnw.net/v0/[some-long-access-token]/index-live.m3u8

    #EXTM3U
    #EXT-X-VERSION:3
    #EXT-X-TARGETDURATION:5
    #ID3-EQUIV-TDTG:2017-10-27T16:53:27
    #EXT-X-MEDIA-SEQUENCE:8788
    #EXT-X-TWITCH-ELAPSED-SECS:17576.000
    #EXT-X-TWITCH-TOTAL-SECS:17589.870
    #EXTINF:2.000,
    index-0000008788-Y6OH.ts
    #EXTINF:2.000,
    index-0000008789-l0QY.ts
    #EXTINF:2.000,
    index-0000008790-gCUV.ts
    #EXTINF:2.000,
    index-0000008791-1ngg.ts
    #EXTINF:2.000,
    index-0000008792-wpQL.ts
    #EXTINF:2.000,
    index-0000008793-koO4.ts
    

    然后,您将index-live.m3u8 替换为列表中的文件名,并请求它获取该剪辑。比如:

    https://video-edge-c61b44.lax01.hls.ttvnw.net/v0/[the-same-long-access-token]/index-0000008793-koO4.ts

    它将是大约 1 秒长的 MPEG-4 流。该列表大约有 6 个文件长,因此如果您全部请求它们,您可以获得大约 6 秒的缓冲区。

    每隔一两秒,index-live.m3u8 就会更新,旧文件会随着新文件添加到底部而滚动。当缓冲区耗尽时,您需要每隔几秒重新请求一次此文件,并请求其中的新剪辑以继续播放。

    【讨论】:

      【解决方案2】:

      使用 Ted Bigham 的answer,您可以获得视频的 m3u8 流。然后,您可以将此流输入到AVPro video from Renderheads 之类的插件中,以在您想要的任何形状或模型上直接统一播放,并具有多种自定义和设置。

      然而,这不是一个免费的插件,可能有替代品。我和他们没有任何关系,但过去使用过这个插件,效果很好。

      p.s 我最初只是想将其发布为评论,并相信 Ted Bigham 回答了您的问题。但由于名誉问题,不允许。

      【讨论】:

        【解决方案3】:

        @Ted Bigham 是否可以仅使用默认的统一视频播放器来执行此操作?

        到目前为止,您所说的一切都非常有效!仅使用 chrome,我就可以打开 .m3u8 并每隔 1 秒下载一次 .ts 文件。使用任何视频播放器,我都可以很好地查看每个视频文件。

        当我尝试通过视频播放器传递 url 时,它显示“无法读取文件”。我什至尝试用.mp4 替换.ts,因为这是受支持的格式。这在我在 Unity 之外测试时有效,但给了我同样的错误。

        这是我的代码。

        using System.Collections;
        using System.Collections.Generic;
        using UnityEngine;
        using UnityEngine.Networking;
        using UnityEngine.Video;
        
        public class TwitchStreamer : MonoBehaviour
        {
        
            public string m3u8 = "https://video-weaver.atl01.hls.ttvnw.net/v1/playlist/Cq4EuEYkh5IqurC4gy3nHqGhPVtUwH_" +
                "5QcQbCatC5Fhit9qbivMQ2rdh2MS_m_2OuLd3VS2mF0eTrCKrz8YTuDO19mcbIBMJL3BUMz4jnNuU_t-e53V51TOtaN3vcCk9n3Qr" +
                "dP0WyLREnVR0n_30d4PlUjjW4_si5Wr2XuePQ0dPtxP6jnsenKnX56YTLohtCN2-FdfSvHQMdfd0aw68FA4h9wawHoIM9-U6YRmPa" +
                "fDsfdCiZr_iToSR6lZi81VoYPVjt7Ygf7xKwhjlNwrvA5SnsAnWQGIOVt4UjDkNLw-hmNMAr7RT0iiDghKXZY1VI6Tuc-umB1VXYE" +
                "7BH5hHbDfHgB3_IYNb0fjoudtSuaZxISyWoazPrw3AibEO7k1-quhdcjarBTGpIi_dlPEp-yZlQOy98_OZY_tqjk8ZWTBIaAAYEG_" +
                "miwqsgH4d6eIfkh3ehyMvPQH1C5dVG9tQcSWPUYU6D6hWhxvJhEr-UC0_BYWIVzX7z_Uf74FJGIEqSQc0d6igiowdMM_lyD8ZV9BE" +
                "7wqQs3RegMPqux-AOfF-_Q7Ki2MBv9u7D9ZRXMH_cm20bTx5-ShEDRnWMApSfXK-9bAGNXUcw8YlBbHYeSN5VxEZMC2oGjcivBsGs" +
                "RPMTQ_yNBSM1S6GxFRIR4nqA-mbdXg3rXMW3V6MNybBb1lrrQeEqF1tdYE0rfxe3Ki5WWkxeKmSjMGbMl1tHCwMaReTYkQnX5Qhjl" +
                "HXXtKLtEIEEhB3cXW3oF05-E_q87s68JQIGgyIEKPiQlTsANR9zRc.m3u8";
        
        
            public float updateClip = 1f, updateFile = 6f;
        
            public VideoPlayer vp;
        
            Queue<string> urls;
        
            void OnEnable()
            {
                StartCoroutine(UpdateFile());
                //InvokeRepeating("UpdateFile", 0f, updateFile);
                InvokeRepeating("UpdateClip", updateClip, updateClip);
                urls = new Queue<string>();
                vp.prepareCompleted += Vp_prepareCompleted;
                vp.errorReceived += Vp_errorReceived;
            }
        
            private void Vp_errorReceived(VideoPlayer source, string message)
            {
                Debug.Log("4567: Playback preparation failed. " + message, source);
            }
        
            private void Vp_prepareCompleted(VideoPlayer source)
            {
                Debug.Log("4567: Playback preparation complete.");
                source.Play();
            }
        
            void OnDisable()
            {
                CancelInvoke();
                StopAllCoroutines();
                vp.prepareCompleted -= Vp_prepareCompleted;
                vp.errorReceived -= Vp_errorReceived;
            }
        
            void UpdateClip()
            {
                //vp.Stop();
                if (urls.Count > 0)
                {
                    vp.url = urls.Dequeue();
                    vp.Prepare();
                    Debug.Log("4567: Prepare playback for " + vp.url);
                }
            }
        
            IEnumerator UpdateFile()
            {
                UnityWebRequest www = UnityWebRequest.Get(m3u8);
                yield return www.SendWebRequest();
        
                if (www.isNetworkError || www.isHttpError)
                {
                    Debug.Log(www.error);
                }
                else
                {
                    // Show results as text
                    //Debug.Log(www.downloadHandler.text);
                    string[] raw = www.downloadHandler.text.Split('\n');
                    foreach (string line in raw)
                    {
                        if (line.Contains("http"))
                        {
                            string cnvrt = line.Replace(".ts", ".mp4");
                            urls.Enqueue(cnvrt);
                            Debug.Log(line + " has been added to stream queue.");
                        }
                    }
                    // Or retrieve results as binary data
                    //byte[] results = www.downloadHandler.data;
                }
                yield return new WaitForSeconds(updateFile);
            }
        }
        

        【讨论】:

          【解决方案4】:

          我相信这个人想知道的是 Twitch API 是否真的检索实时视频源并将数据传递给应用程序。简短的回答是,它没有。 Twitch API 不允许您获取实时视频源,只能获取有关它的信息。

          您可以获得告诉您频道名称、游戏和链接的字符串,以将您带到该频道。您还可以获取他们的频道背景或预览作为图像文件。您不能做的是获取视频文件或流式视频数据。最好的办法是获取 URL 并链接到它们。

          我能想到的在任何游戏中获得实时流的唯一方法就是让它成为玩家的。本质上,您将编写一种方法,他们可以通过该方法在游戏本身中流式传输他们的游戏,获取流数据并将其复制到某个变量或类中,然后再将其上传到 Twitch,这样您就可以同时使用数据它正在广播。但是如果你想在你的游戏中检索一些随机流媒体的游戏并将其显示在电脑屏幕上,恐怕你不能这样做。无论如何,不​​在 Unity 中。

          【讨论】:

            【解决方案5】:
            • 您可以将抽搐流嵌入到网站中
            • Unity 有网页浏览器插件(see)

            因此,如果您结合这些想法,您可以通过运行应用内浏览器来统一显示 twitch 流,该浏览器将运行嵌入您想要的流的自定义网页。我不知道你会从中得到什么样的表现,但这听起来很简单。它可能不像直接在纹理上显示流那么简单,但它至少比 Thomas 建议的学习 C、网络编程、视频处理等更简单。

            【讨论】:

              【解决方案6】:

              这是一件棘手的事情。您需要来自 Twitch 的 API 密钥,该程序不仅可以与您选择的 API 建立连接,还可以建立数据流。我建议从用 C 等不太专业的语言学习基本的网络编程开始,然后从那里开始工作。在您了解了基础知识后,请回过头来提出更具体的问题。在这个问题所在的状态下,我不能做那么多。

              与其他所有事情一样,这绝对是可能的,只是在 C# 中可能不行。为了不破坏游戏的性能,我建议编写一个单独的程序,将数据馈送到游戏中,而游戏不会直接抓取数据。

              一旦你了解了网络编程,我会跳到 API 上的 twitch 开发聊天,发现 here

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2015-07-30
                • 2014-09-13
                • 1970-01-01
                • 2022-07-19
                • 2016-07-14
                相关资源
                最近更新 更多