Um servidor web foi criado usando GoLang que serve HTML/JS/CSS e imagens. Quando o servidor tentou fornecer um arquivo de vídeo MP4, o vídeo falhou ao carregar, mostrando apenas controles de vídeo.
Ao examinar os arquivos de vídeo, descobriu-se que o vídeo menor funcionou enquanto o vídeo maior não. O problema estava relacionado ao tamanho do vídeo e ao comportamento de buffer padrão do navegador.
Suporte para solicitação de intervalo:
Para vídeos maiores que um determinado tamanho, o navegador requer o servidor para oferecer suporte a solicitações de intervalo (servimento parcial de conteúdo). Isso permite que o navegador busque apenas a parte do vídeo necessária para reprodução, evitando que o arquivo inteiro seja carregado na memória.
Nesse caso, o código GoLang não foi configurado para lidar com solicitações Range. A implementação fornecida simplesmente serviu o arquivo inteiro como uma única resposta. Como resultado, o navegador não conseguiu reproduzir o vídeo maior.
Para resolver o problema, foram executadas as seguintes etapas:
Como alternativa , se http.FileServe() não for preferido, o tratamento de solicitação de intervalo personalizado poderá ser implementado. Isso envolve definir os seguintes cabeçalhos na resposta:
Para solicitações de intervalo, o servidor deve retornar um código de status HTTP 206 Conteúdo parcial em vez de 200 OK.
O tratamento de solicitação de intervalo personalizado foi implementado da seguinte maneira:
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 em loop:
Para garantir que o vídeo seja repetido, a seguinte lógica foi adicionada:
if contentType == "video/mp4" {
http.ServeFile(w, r, path)
} else {
w.Header().Add("Content-Type", contentType)
w.Write(data)
}
Isso usa http.ServeFile() para vídeos MP4, que lida corretamente com o loop.
Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.
Copyright© 2022 湘ICP备2022001581号-3