<p>I am writing this simple MJPEG relay and I have it working for 1 source to n clients. It reads a MJPEG stream, reads the response body and header and sends it to any other client. The point of this is to replicate the stream on a server without putting to much load on the IP camera that can't handle many connections at once. Now I wanna expand this to work with N number of cameras as well as N number of clients. My old code for 1 camera to N client looks like this:</p>
<pre><code>package mjpeg
import (
"flag"
"image"
"image/jpeg"
"io"
"log"
"net/http"
"os"
"sync"
"github.com/mattn/go-mjpeg"
)
// Flags for the source MJPEG stream and the server port
var url = flag.String("url", "", "URL for the MJPEG stream")
var addr = flag.String("addr", ":8080", "Port to listen on")
// RelayStream reads a MJPEG stream and creates a relay for n number of clients to access
func RelayStream() error {
// Parse the input flags for port and MJPEG source url
flag.Parse()
if *url == "" {
flag.Usage()
os.Exit(1)
}
log.Println("Relay stream started")
// Serve the MJPEG video in the default route of /
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
// Read the mjpeg stream
resp, err := http.Get(*url)
if err != nil {
log.Println("Error fetching response")
return
}
// Copy headers from the response to our relay
w.Header().Set("Content-Type", resp.Header.Get("Content-Type"))
w.Header().Set("Content-Length", resp.Header.Get("Content-Length"))
// Copy the body
io.Copy(w, resp.Body)
resp.Body.Close()
log.Println("Relay stream stopped")
})
// Listen on the specifed port and serve the MJPEG
err := http.ListenAndServe(*addr, nil)
if err != nil {
log.Println("Error listening on the port")
return err
}
return nil
}
</code></pre>
<p>Now I wanna pass in a list of URLs in the form of url []string instead of using 1 url. I can probably generate the route strings using some sort of uuid generator. But how would setup reading and serving stream for each camera?</p>
<hr/>**评论:**<br/><br/>mattn: <pre><p>For example, "/XXXXXXXXXXXXX" given as md5 hash of camera URL?</p></pre>zeus-man: <pre><p>Yup something like that. Hey are you the guy behind <a href="https://github.com/mattn/go-mjpeg" rel="nofollow">https://github.com/mattn/go-mjpeg</a> and the sql library? Love your stuff! I found the go-mjpeg very useful and even contributed a little. Cheers!</p></pre>janderssen: <pre><p>In the handler you could use the gorilla web toolkit : github.com/gorilla</p>
<p>Then you could define your route as "/{cameraId}", then inside the handler it is as simple as follows :</p>
<pre><code>func restConnectToCamera(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
cameraId := vars["cameraId"]
}
</code></pre>
<p>I think this is what you are trying to do ?</p>
<p>Cheers and hope this helps</p></pre>zeus-man: <pre><p>Ah yes. This solves my initial pain with the route generation.</p></pre>zeus-man: <pre><p>On an unrelated note is there any example of doing this but with httprouter instead?</p></pre>silviucm: <pre><pre><code>// define your route
router.GET("/myfeeds/:camId", streamStuff)
...
// handler
func streamStuff(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
id := params.ByName("camId")
...
}
</code></pre></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传