[Go & Fiber] 동영상 스트리밍 구현

320x100

Go & Fiber는 이미 설치되어 있다고 가정합니다.

아니라면, 아래 포스팅을 참고해주세요.

https://readerr.tistory.com/100

 

소스 저장소

https://github.com/WOOOOOOOONG/GO-Fiber-Streaming

 

GitHub - WOOOOOOOONG/GO-Fiber-Streaming: 동영상 스트리밍 코드입니다.

동영상 스트리밍 코드입니다. Contribute to WOOOOOOOONG/GO-Fiber-Streaming development by creating an account on GitHub.

github.com

 

결과

 

패키지 다운로드

go get -u github.com/gorilla/websocket
go get -u github.com/gorilla/mux

 

파일 구조

public
  - index.html
server.go

 

백엔드 코드 (server.go)

참고로, 반드시 48번째줄 코드에서 경로와 비디오 파일을 별도로 넣어주셔야 합니다.

package main

import (
    "log"
    "net/http"
    "os"
    "path/filepath"
    "time"

    "github.com/gorilla/mux"
    "github.com/gorilla/websocket"
)

var upgrader = websocket.Upgrader{
    CheckOrigin: func(r *http.Request) bool {
        return true
    },
}

func main() {
    r := mux.NewRouter()

    // 사이트 홈을 public/index.html로 지정
    r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        http.ServeFile(w, r, "public/index.html")
    })

    r.HandleFunc("/ws", handleWebSocket)
    r.HandleFunc("/video/{filename}", handleVideoStream)

    log.Println("Server started on http://localhost:3000")
    log.Fatal(http.ListenAndServe(":3000", r))
}

func handleWebSocket(w http.ResponseWriter, r *http.Request) {
    conn, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        log.Println("WebSocket upgrade failed:", err)
        return
    }
    defer conn.Close()

    // 클라이언트에서 WebSocket 연결이 성공적으로 열리면 해당 로직이 실행됩니다.
    log.Println("WebSocket connection established")

    // 동영상 파일을 열어서 전송할 준비를 합니다.
/   // 해당 경로에 반드시 파일을 넣어주세요.
    file, err := os.Open("path/to/video.mp4"
    if err != nil {
        log.Println("Failed to open video file:", err)
        return
    }
    defer file.Close()

    bufferSize := 1024 * 4 // 4KB의 버퍼 크기로 설정합니다.
    buffer := make([]byte, bufferSize)

    // 파일을 읽어서 WebSocket을 통해 클라이언트로 전송합니다.
    for {
        // 버퍼에 데이터를 읽어옵니다.
        n, err := file.Read(buffer)
        if err != nil {
            log.Println("Failed to read video file:", err)
            break
        }

        // 버퍼의 내용을 클라이언트로 전송합니다.
        if err := conn.WriteMessage(websocket.BinaryMessage, buffer[:n]); err != nil {
            log.Println("Failed to send video data over WebSocket:", err)
            break
        }

        // 전송 속도 제어를 위해 10ms 대기합니다.
        time.Sleep(10 * time.Millisecond)
    }

    log.Println("Video streaming completed")
}

func handleVideoStream(w http.ResponseWriter, r *http.Request) {
    vars := mux.Vars(r)
    filename := vars["filename"]
    filePath := filepath.Join(".", "videos", filename)

    file, err := os.Open(filePath)
    if err != nil {
        log.Println("Failed to open video file:", err)
        http.NotFound(w, r)
        return
    }
    defer file.Close()

    w.Header().Set("Content-Type", "video/mp4")
    http.ServeContent(w, r, "", time.Now(), file)
}

 

클라이언트 코드 (public/index.html)

<!DOCTYPE html>
<html>
<head>
    <title>Video Streaming</title>
    <style>
        #video-container {
            width: 640px;
            height: 480px;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    <div id="video-container">
        <video id="video-player" controls></video>
    </div>

    <script>
        const videoPlayer = document.getElementById('video-player');

        // WebSocket 연결
        const ws = new WebSocket('ws://localhost:3000/ws');

        // WebSocket 이벤트 리스너
        ws.onopen = function(event) {
            console.log('WebSocket connection opened');
        };

        ws.onmessage = function(event) {
            // 서버로부터 동영상 데이터 수신 시 처리
            const data = event.data;
            const videoBlob = new Blob([data], { type: 'video/mp4' });
            const videoUrl = URL.createObjectURL(videoBlob);
            videoPlayer.src = videoUrl;
        };

        ws.onclose = function(event) {
            console.log('WebSocket connection closed');
        };
    </script>
</body>
</html>

 

실행

go run server.go

이후 localhost:3000에서 확인

 

그럼, 오늘 하루도 좋은 하루 되세요!

320x100

'Go' 카테고리의 다른 글

[Go & Fiber] 채팅 시스템 구현  (0) 2023.07.02
Go & Fiber framework 설치  (0) 2023.07.02