"일꾼이 일을 잘하려면 먼저 도구를 갈고 닦아야 한다." - 공자, 『논어』.
첫 장 > 프로그램 작성 > 내 GoLang 웹서버가 대용량 MP4 비디오를 제공하지 못하는 이유는 무엇입니까?

내 GoLang 웹서버가 대용량 MP4 비디오를 제공하지 못하는 이유는 무엇입니까?

2024-11-08에 게시됨
검색:397

Why does my GoLang webserver fail to serve large MP4 videos?

MP4 비디오를 제공하는 GoLang HTTP 웹서버

챌린지

HTML/JS/CSS 및 이미지를 제공하는 GoLang을 사용하여 웹서버를 만들었습니다. 서버가 MP4 비디오 파일을 제공하려고 시도했을 때 비디오가 로드되지 않고 비디오 컨트롤만 표시되었습니다.

조사

비디오 파일을 조사한 결과 더 작은 비디오는 작동하는 것으로 나타났습니다. 더 큰 비디오는 그렇지 않았습니다. 문제는 비디오 크기 및 브라우저의 기본 버퍼링 동작과 관련이 있습니다.

범위 요청 지원:

특정 크기보다 큰 비디오의 경우 브라우저에 서버가 필요합니다. Range 요청을 지원합니다(부분 콘텐츠 제공). 이를 통해 브라우저는 재생에 필요한 비디오 부분만 가져올 수 있으므로 전체 파일이 메모리에 로드되는 것을 방지할 수 있습니다.

이 경우 GoLang 코드는 Range 요청을 처리하도록 구성되지 않았습니다. 제공된 구현은 단순히 전체 파일을 단일 응답으로 제공했습니다. 결과적으로 브라우저에서 더 큰 동영상을 재생할 수 없습니다.

해결 방법

문제를 해결하기 위해 다음 단계를 수행했습니다.

  1. http.FileServe(): 사용 http.FileServe() 메서드는 기본적으로 Range 요청을 처리합니다. 이 방법을 사용하여 비디오 파일을 제공함으로써 서버는 부분 콘텐츠를 브라우저에 제공할 수 있었습니다.
  2. 사용자 정의 범위 요청 처리 구성:

대안으로 , http.FileServe()가 선호되지 않는 경우 사용자 정의 범위 요청 처리를 구현할 수 있습니다. 여기에는 응답에 다음 헤더를 설정하는 작업이 포함됩니다.

  • Accept-Ranges: bytes
  • Content-Length(파일 크기)
  • Content-Range(바이트 요청된 범위)
  1. HTTP 상태 코드 206 사용:

범위 요청의 경우 서버는 HTTP 상태 코드 206을 반환해야 합니다. 200 대신 부분 콘텐츠 OK.

구현

사용자 정의 범위 요청 처리는 다음 방식으로 구현되었습니다.

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)))
    }
}

동영상 반복:

동영상이 반복되도록 하기 위해 다음 논리가 추가되었습니다.

if contentType == "video/mp4" {
    http.ServeFile(w, r, path)
} else {
    w.Header().Add("Content-Type", contentType)
    w.Write(data)
}

MP4 비디오에 http.ServeFile()을 사용하여 루프를 올바르게 처리합니다.

최신 튜토리얼 더>

부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.

Copyright© 2022 湘ICP备2022001581号-3