本文介绍了如何在Go中手动代理应用程序/八位字节流(实时视频)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试构建一个应用程序,该应用程序将充当具有缓存功能的流代理服务器.问题是,我想手动执行此操作,而不使用 NewSingleHostReverseProxy .手动意味着执行以下步骤:

I am trying to build an application which would act as a streaming proxy server with caching features. The thing is, I want to do it manually without using NewSingleHostReverseProxy. Manually means performing these steps:

  1. 对服务器执行单个 GET 请求
  2. 读取 resp.Body 进行缓冲并写入连接的客户端
  1. Perform single GET request to the server
  2. Read resp.Body to buffer and write to connected client(s)

问题是VLC没有播放任何内容.如果我直接访问流-VLC可以毫无问题地播放它,但是如果我通过GO进行操作-VLC(以及Kodi)只是保持缓冲并且永远不会开始播放.

And the issue is that VLC doesn't play anything. If I access stream directly - VLC plays it without problems, but if I do it via GO - VLC (as well as Kodi) just keeps buffering and never starts playing.

我尝试过但没有用的东西:

Things I've tried, but did not work:

  1. io.Copy(...)
  2. bufio 读取器/扫描器,并写入连接的客户端.冲洗也无济于事.
  1. io.Copy(...)
  2. bufio reader/scanner and writing to the connected client. Flushing also did not help.

这是 curl -v< stream_url> 所说的(直接访问流url):

This is what curl -v <stream_url> says (accessing streaming url directly):

...
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 Ok
< Server: Myserver
< Cache-Control: no-cache
< Pragma: no-cache
< Content-Type: application/octet-stream
< Access-Control-Allow-Origin: *
< Connection: close
<
Warning: Binary output can mess up your terminal. Use "--output -" to tell
Warning: curl to output it to your terminal anyway, or consider "--output
Warning: <FILE>" to save to a file.
* Failed writing body (0 != 2896)
* Closing connection 0

这是 curl -v< my_app_url> 所说的:

...
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Access-Control-Allow-Origin: *
< Cache-Control: no-cache
< Content-Type: application/octet-stream
< Pragma: no-cache
< Server: Myserver
< Date: Sun, 29 Dec 2019 09:13:44 GMT
< Transfer-Encoding: chunked
<
Warning: Binary output can mess up your terminal. Use "--output -" to tell
Warning: curl to output it to your terminal anyway, or consider "--output
Warning: <FILE>" to save to a file.
* Failed writing body (0 != 14480)
* Failed reading the chunked-encoded stream
* Closing connection 0


问题似乎在这里,但是我该如何解决?


Seems the issue is here, but how do I solve it?

好:

* Failed writing body (0 != 2896)
* Closing connection 0

坏:

* Failed writing body (0 != 14480)
* Failed reading the chunked-encoded stream
* Closing connection 0


还添加源代码,例如:


Also adding a source code for example:

func main() {
    http.HandleFunc("/stream", func(w http.ResponseWriter, r *http.Request) {
        resp, err := http.Get("http://example.com/stream/videostream")
        if err != nil {
            panic(err)
        }
        defer resp.Body.Close()
        reader := bufio.NewReader(resp.Body)
        buf := make([]byte, 1024)
        for {
            k, _ := reader.Read(buf)
            if k == 0 {
                break
            }
            w.Write(buf)
        }
    })
    log.Fatal(http.ListenAndServe(":8080", nil))
}

推荐答案

我正在构建一个动态的 M3U 播放列表,并将 .m3u8 结尾放在每个链接上.所有链接都是未知类型,因此我认为媒体播放器将仅查看 Content-Type 并相应地处理媒体,但实际上,它们也查看URL结尾(URL是否包含 .m3u8).

I was building a dynamic M3U playlist and putting .m3u8 ending on each link. All the links are of unknown type, so I thought media players will just look at Content-Type and handle media accordingly, but actually they look at URL endings as well (whether URL contains .m3u8 or not).

如果您将链接放在 .m3u8 的末尾,则将该链接的Content-Type设置为 application/octet-stream 并提供实际的 application/八位字节流流-播放器永远不会开始显示任何视频流.解决方案-如果URL不是 m3u8 格式的媒体,请勿将 .m3u8 附加到URL.没有 m3u8 ,媒体播放器仍然可以播放视频.

If you put at the end of the link .m3u8, then set that link's Content-Type as application/octet-stream and provide actual application/octet-stream stream - players will never start showing any video stream. Solution - do not append .m3u8 to URL if that URL is not m3u8 format media. Without m3u8 media players can still show the video.

这篇关于如何在Go中手动代理应用程序/八位字节流(实时视频)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-23 20:28