首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在unity3D应用程序中显示Twitch.tv流

在unity3D应用程序中显示Twitch.tv流
EN

Stack Overflow用户
提问于 2016-01-18 22:39:30
回答 6查看 5.5K关注 0票数 13

我想做一个可以观看当前Twitch.tv直播流的Unity3D应用程序。

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

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

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

非常感谢,并向我致以最良好的问候

EN

回答 6

Stack Overflow用户

发布于 2017-10-28 01:13:19

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

从twitch获取请求的正确URL需要几个步骤,而这些步骤可能会随着时间的推移而改变。您必须在播放流的同时检查当前的twitch页面,以查看javascript如何构建请求(url和头)。

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

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

代码语言:javascript
复制
#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
EN

Stack Overflow用户

发布于 2018-03-22 16:47:50

使用Ted Bigham的answer,您可以获得视频的m3u8流。然后,您可以将此流传输到像AVPro video from Renderheads这样的插件中,通过各种自定义和设置,直接在任何形状或模型上统一播放。

然而,这不是一个免费的插件,可能还有其他的选择。我与他们没有任何关系,但在过去使用过这个插件,效果很好。

附言:我最初只是想把这篇文章作为评论,我相信Ted Bigham已经回答了你的问题。但由于声誉的原因,我不被允许。

票数 1
EN

Stack Overflow用户

发布于 2020-04-07 06:01:09

@Ted Bigham有没有使用默认的unity视频播放器就能做到这一点?

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

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

这是我的代码。

代码语言:javascript
复制
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);
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34857327

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档