英文:
GoLang - Seeking through a video (serving as bytes)
问题
我正在使用golang编写一个服务器,并成功实现了基本的.mp4文件服务。它通过字节流进行传输。问题是我无法在视频中进行定位/跳转。我尝试在Stack Overflow和Google上搜索答案,但没有找到解决方法。
以下是我的代码:
package main
import (
    "net/http"
    "io/ioutil"
    "fmt"
    "os"
    "log"
    "bytes"
)
func ServeHTTP(w http.ResponseWriter, r *http.Request) {
    // 读取生成的receipt.pdf文件并将其流式传输到浏览器
    streamPDFbytes, err := ioutil.ReadFile("./video.mp4")
    log.Println(r)
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }
    b := bytes.NewBuffer(streamPDFbytes)
    // 直接流式传输到客户端(浏览器)
    w.Header().Set("Content-type", "video/mp4")
    if _, err := b.WriteTo(w); err != nil { // <----- 这里!
        fmt.Fprintf(w, "%s", err)
    }
    w.Write([]byte("Video Completed"))
}
func main() {
    http.Handle("/", new(MyHandler))
    http.ListenAndServe(":8080", nil)
}
有人知道如何在golang中实现定位吗?
谢谢,祝您有愉快的一天!
英文:
I'm writing a server in golang and I got it to serve a basic .mp4 file. It serves it by bytes. The problem is that I can not seek/skip through the video. I've tried searching throughout stackover flow and google to find an answer but I came up short..
Here is my code:
package main
import (
    "net/http"
    "io/ioutil"
    "fmt"
    "os"
    "log"
    "bytes"
)
func ServeHTTP(w http.ResponseWriter, r *http.Request) {
           // grab the generated receipt.pdf file and stream it to browser
           streamPDFbytes, err := ioutil.ReadFile("./video.mp4")
           log.Println(r)
           if err != nil {
                   fmt.Println(err)
                   os.Exit(1)
           }
           b := bytes.NewBuffer(streamPDFbytes)
           // stream straight to client(browser)
           w.Header().Set("Content-type", "video/mp4")
           if _, err := b.WriteTo(w); err != nil { // <----- here!
                   fmt.Fprintf(w, "%s", err)
           }
           w.Write([]byte("Video Completed"))
}
func main() {
    http.Handle("/", new(MyHandler))
    http.ListenAndServe(":8080", nil)
}
Does anyone have the answer to how seeking works in golang?
Thanks,
Have a great day!
答案1
得分: 5
在Go语言中,实现支持定位的最简单的流式传输MP4视频的方法如下:
package main
import (
	"net/http"
)
func main() {
	fs := http.FileServer(http.Dir("."))
	http.Handle("/", http.StripPrefix("/", fs))
	http.ListenAndServe(":8080", nil)
}
视频将在 http://localhost:8080/video.mp4 上可用。
更复杂的方法如下:
package main
import (
	"log"
	"net/http"
	"os"
	"time"
)
func ServeHTTP(w http.ResponseWriter, r *http.Request) {
	video, err := os.Open("./video.mp4")
	if err != nil {
		log.Fatal(err)
	}
	defer video.Close()
	http.ServeContent(w, r, "video.mp4", time.Now(), video)
}
func main() {
	http.HandleFunc("/", ServeHTTP)
	http.ListenAndServe(":8080", nil)
}
如果你需要更灵活的方法,你可以实现自己的渐进式流式传输服务器。
在你的代码中,你忘记添加和处理 Range/Accept-Range 头部,这就是为什么 FF 和 Chrome 都没有显示进度条。但是,我认为将整个MP4文件保存在内存中并不是一个好主意。
英文:
The simplest way to stream MP4 video on Go with seeking support is
package main
import (
	"net/http"
)
func main() {
	fs := http.FileServer(http.Dir("."))
	http.Handle("/", http.StripPrefix("/", fs))
	http.ListenAndServe(":8080", nil)
}
And video will be available at http://localhost:8080/video.mp4
More complex is
package main
import (
	"log"
	"net/http"
	"os"
	"time"
)
func ServeHTTP(w http.ResponseWriter, r *http.Request) {
	video, err := os.Open("./video.mp4")
	if err != nil {
		log.Fatal(err)
	}
	defer video.Close()
	http.ServeContent(w, r, "video.mp4", time.Now(), video)
}
func main() {
	http.HandleFunc("/", ServeHTTP)
	http.ListenAndServe(":8080", nil)
}
If you need something more flexible you should implement your own progressive streaming server.
In your code you forgot to add and process Range/Accept-Range headers that's why nor FF, nor Chrome doesn't show you seek bar but anyway I don't think that keeping whole MP4 file in memory is good idea.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论