Se creó un servidor web utilizando GoLang que sirve HTML/JS/CSS e imágenes. Cuando el servidor intentó proporcionar un archivo de video MP4, el video no se pudo cargar y solo mostró controles de video.
Al examinar los archivos de video, se descubrió que el video más pequeño funcionaba mientras el video más grande no lo hizo. El problema estaba relacionado con el tamaño del video y el comportamiento de almacenamiento en búfer predeterminado del navegador.
Soporte de solicitud de rango:
Para videos de más de cierto tamaño, el navegador requiere el servidor para admitir solicitudes de rango (servicio de contenido parcial). Esto permite que el navegador busque solo la parte del video necesaria para reproducir, evitando que el archivo completo se cargue en la memoria.
En este caso, el código GoLang no se configuró para manejar solicitudes de rango. La implementación proporcionada simplemente sirvió todo el archivo como una única respuesta. Como resultado, el navegador no pudo reproducir el video más grande.
Para resolver el problema, se tomaron los siguientes pasos:
Alternativamente , si no se prefiere http.FileServe(), se puede implementar el manejo de solicitudes de rango personalizado. Esto implica configurar los siguientes encabezados en la respuesta:
Para solicitudes de rango, el servidor debe devolver un código de estado HTTP de 206 Contenido parcial en lugar de 200 OK.
El manejo de solicitudes de rango personalizado se implementó de la siguiente manera:
func (vh *viewHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
path := r.URL.Path[1:]
data, err := ioutil.ReadFile(string(path))
if err == nil {
var contentType string
if strings.HasSuffix(path, ".mp4") {
contentType = "video/mp4"
size := binary.Size(data)
if size > 0 {
requestedBytes := r.Header.Get("Range")
w.Header().Add("Accept-Ranges", "bytes")
w.Header().Add("Content-Length", strconv.Itoa(size))
w.Header().Add("Content-Range", "bytes " requestedBytes[6:len(requestedBytes)] strconv.Itoa(size-1) "/" strconv.Itoa(size))
w.WriteHeader(206)
}
} else {
w.Header().Add("Content-Type", contentType)
w.Write(data)
}
} else {
log.Println("ERROR!")
w.WriteHeader(404)
w.Write([]byte("404 - " http.StatusText(404)))
}
}
Vídeo en bucle:
Para garantizar que el vídeo se reproduzca en bucle, se agregó la siguiente lógica:
if contentType == "video/mp4" {
http.ServeFile(w, r, path)
} else {
w.Header().Add("Content-Type", contentType)
w.Write(data)
}
Esto utiliza http.ServeFile() para videos MP4, que maneja correctamente el bucle.
Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.
Copyright© 2022 湘ICP备2022001581号-3