gofiber / adaptor

🧬 Adaptor middleware to convert net/http handlers from/to Fiber request handlers
MIT License
181 stars 11 forks source link

ResponseWriter.Write() not writing to client #116

Open seriousm4x opened 2 years ago

seriousm4x commented 2 years ago

So I tried to convert a video with ffmpeg and stream the output to the client while encoding. Since fiber doesn't support streaming I tried it with net/http and it works without problems.

Then i found this adaptor and tried to wrap my function inside it but the ffmpeg output never reaches the browser.

I guess that it's got something to do with ResponseWriter.Write() and the adaptor but I don't know what.

Here is the example (make sure to have ffmpeg):

package main

import (
    "fmt"
    "io"
    "net/http"
    "os/exec"

    "github.com/gofiber/adaptor/v2"
    "github.com/gofiber/fiber/v2"
)

func main() {
    // New fiber app
    app := fiber.New()

    // http.HandlerFunc -> fiber.Handler
    app.Get("/", adaptor.HTTPHandlerFunc(greet))

    // Listen on port 3000
    app.Listen(":3000")
}

func greet(w http.ResponseWriter, r *http.Request) {
    cmd := exec.Command("ffmpeg",
        "-i", "https://test-streams.mux.dev/x36xhzz/url_6/193039199_mp4_h264_aac_hq_7.m3u8",
        "-c", "copy",
        "-bsf:a", "aac_adtstoasc",
        "-movflags", "frag_keyframe+empty_moov",
        "-f", "mp4",
        "-")

    stdout, err := cmd.StdoutPipe()
    if err != nil {
        panic(err)
    }

    if err = cmd.Start(); err != nil {
        fmt.Println(err)
        panic(err)
    }
    fmt.Println("ffmpeg running")

    data := make([]byte, 1024)
    for {
        w.Header().Set("Content-Type", "video/mp4")
        w.Header().Add("Content-Disposition", "attachment; filename=test.mp4")
        n, err := stdout.Read(data)
        if err == io.EOF {
            fmt.Println("eof")
            break
        }
        if n > 0 {
            valid_data := data[:n]
            if _, err = w.Write(valid_data); err != nil {
                fmt.Println("client disconnected")
                cmd.Process.Kill()
                break
            }
        }
    }
}
gaby commented 1 year ago

@seriousm4x Streaming is supported by using app.Server().StreamRequestBody = true

Full example here: https://github.com/gofiber/recipes/blob/master/stream-request-body/main.go

leonklingele commented 1 year ago

@seriousm4x has your issue been resolved in the meantime? Have you tried @gaby's suggestion?

seriousm4x commented 1 year ago

@leonklingele All I remember was I couldn't get it to work. I ended up using gin. Sorry.