简体   繁体   English

视频流中的导航,golang中的反向代理

[英]navigation in video stream, reverse proxy in golang

I'm testing a reverse proxy in go. 我正在测试反向代理。 Mainly for playing videos though underlying nginx and streaming videos from other backend servers. 主要用于通过底层nginx播放视频和来自其他后端服务器的流式视频。

Problem is when navigating through video. 问题是在视频中导航时。 For example when playing with vlc through proxy - video starts normally, but stops when trying to navigate. 例如,通过代理播放vlc时-视频正常启动,但在尝试导航时停止。 But if i play this video directly from nginx - it works fine. 但是,如果我直接从nginx播放此视频-效果很好。

I expected that on navigation player would create new connection with Range: N- header, but there is no new connections, only when starting video again. 我希望在导航播放器上使用Range: N-标头创建新的连接,但是没有新的连接,只有在再次启动视频时才可以。

Question: 题:

How does player navigates, when playing video stream? 播放视频流时,播放器如何导航? What requests it sends to server? 它向服务器发送什么请求? Maybe i'm missing something in connection handling? 也许我在连接处理中缺少什么?

This is very basic version for testing, it streams video from local nginx, (local video url - http://localhost/31285611 ): 这是用于测试的非常基本的版本,它从本地nginx流视频(本地视频url- http://localhost/31285611 ):

package main

import (
    "net/http"
)

func main() {
    (&proxy{}).start()
}

type proxy struct {
    // ...
}

func (p *proxy) start() {
    http.HandleFunc("/play", p.connection)
    http.ListenAndServe("localhost:8040", nil)
}

func (p *proxy) connection(w http.ResponseWriter, r *http.Request) {
    disconnect := make(chan bool, 1)
    go p.send(w, r, disconnect)

    // ...

    <-disconnect
}


func (p *proxy) send(rv http.ResponseWriter, rvq *http.Request, disconnect chan bool) {

    rq, _ := http.NewRequest("GET", "http://localhost/31285611", rvq.Body)
    rq.Header = rvq.Header

    rs, _ := http.DefaultClient.Do(rq)
    for k, v := range rs.Header {
        rv.Header().Set(k, v[0])
    }
    rv.WriteHeader(http.StatusOK)

    buf := make([]byte, 1024)

    // for testing sending only first part.
    for i := 0; i < 100000; i++ {
        n, e := rs.Body.Read(buf[0:])
        if n == 0 || e != nil {
            break
        }
        rv.Write(buf[0:])
    }

    disconnect <- true

}

Update (headers dump): 更新(标题转储):

First player connection: 第一个玩家连接:

map[User-Agent:[VLC/2.0.0 LibVLC/2.0.0] Range:[bytes=0-] Connection:[close] Icy-Metadata:[1]]

Response from nginx, when creating connection in go: 在go中创建连接时来自nginx的响应:

map[Server:[nginx/1.3.4] Date:[Tue, 23 Apr 2013 13:29:00 GMT] Content-Type:[application/octet-stream] Content-Length:[8147855699] Last-Modified:[Tue, 21 Aug 2012 20:47:20 GMT] Etag:["5033f3d8-1e5a66953"] Content-Range:[bytes 0-8147855698/8147855699]]

I know it's not really answering your question (and I don't have enough points to comment yet, so sorry for providing this as an answer!) but have you tried using Go's built in http.ReverseProxy ( http://golang.org/pkg/net/http/httputil/#ReverseProxy )? 我知道它并没有真正回答您的问题(并且我还没有足够的意见要发表,所以很抱歉提供此答案!),但是您是否尝试过使用内置在http.ReverseProxy( http://golang.org中的 Go) / pkg / net / http / httputil /#ReverseProxy )?

There seems to be a nice, simple example here https://groups.google.com/forum/?fromgroups=#!topic/golang-nuts/1ufEw_IEVM4 which I've very slightly modified below: 似乎这里是一个不错的,简单的例子https://groups.google.com/forum/?fromgroups=#!topic/golang-nuts/1u​​fEw_IEVM4我已经以下略作修改:

package main

import (
    "log"
    "net/http"
    "net/http/httputil"
    "net/url"
)

func main() {
    proxy := httputil.NewSingleHostReverseProxy(&url.URL{Scheme: "http", Host: "www.google.com", Path: "/"})

    err := http.ListenAndServe(":8080", proxy)
    if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}

See if that does the job. 看看是否能胜任。

Also, in the previously linked Google Groups discussion, there is mention of NginX having issues with chunked encoding. 另外,在之前链接的Google网上论坛讨论中,提到了NginX在分块编码方面存在问题。 It might be worth checking if this is related. 可能值得检查是否相关。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM