سؤال
كيف يمكنني الأنابيب استجابة HTTP كما في NodeJS.هنا مقتطف أنا أستخدم في NodeJS:
request({
url: audio_file_url,
}).pipe(ffmpeg_process.stdin);
كيف يمكن تحقيق نفس النتيجة في الذهاب ؟
أنا أحاول أن الأنابيب دفق الصوت من HTTP إلى FFmpeg العملية بحيث يحول ذلك على الطاير وإرجاع الملف الذي تم تحويله مرة أخرى إلى العميل.
فقط لذلك من الواضح أن الجميع هنا هو بلدي شفرة المصدر حتى الآن:
func encodeAudio(w http.ResponseWriter, req *http.Request) {
path, err := exec.LookPath("youtube-dl")
if err != nil {
log.Fatal("LookPath: ", err)
}
path_ff, err_ff := exec.LookPath("ffmpeg")
if err != nil {
log.Fatal("LookPath: ", err_ff)
}
streamLink := exec.Command(path,"-f", "140", "-g", "https://www.youtube.com/watch?v=VIDEOID")
var out bytes.Buffer
streamLink.Stdout = &out
cmdFF := exec.Command(path_ff, "-i", "pipe:0", "-acodec", "libmp3lame", "-f", "mp3", "-")
resp, err := http.Get(out.String())
if err != nil {
log.Fatal(err)
}
// pr, pw := io.Pipe()
defer resp.Body.Close()
cmdFF.Stdin = resp.Body
cmdFF.Stdout = w
streamLink.Run()
//get ffmpeg running in another goroutine to receive data
errCh := make(chan error, 1)
go func() {
errCh <- cmdFF.Run()
}()
// close the pipeline to signal the end of the stream
// pw.Close()
// pr.Close()
// check for an error from ffmpeg
if err := <-errCh; err != nil {
// ff error
}
}
خطأ: 2014/07/29 23:04:02 الحصول على :غير معتمد على بروتوكول مخطط ""
المحلول
وهنا إجابة ممكنة باستخدام معيار http معالج وظيفة.ليس لدي برامج لاختبار هذا مباشرة, ولكنها لا تعمل مع بعض بسيطة قذيفة الأوامر الدائمة في كوكيل.
func encodeAudio(w http.ResponseWriter, req *http.Request) {
streamLink := exec.Command("youtube-dl", "-f", "140", "-g", "https://www.youtube.com/watch?v=VIDEOID")
out, err := streamLink.Output()
if err != nil {
log.Fatal(err)
}
cmdFF := exec.Command("ffmpeg", "-i", "pipe:0", "-acodec", "libmp3lame", "-f", "mp3", "-")
resp, err := http.Get(string(out))
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
cmdFF.Stdin = resp.Body
cmdFF.Stdout = w
if err := cmdFF.Run(); err != nil {
log.Fatal(err)
}
}
نصائح أخرى
http.Request.Body
هو io.ReadCloser
, لذا هل يمكن أن الأنابيب في exec.Cmd
.ستدين:
func Handler(rw http.ResponseWriter, req *http.Request) {
cmd := exec.Command("ffmpeg", other, args, ...)
cmd.Stdin = req.Body
go func() {
defer req.Body.Close()
if err := cmd.Run(); err != nil {
// do something
}
}()
//redirect the user and check for progress?
}
//تحرير لقد أسأت فهم السؤال ولكن الجواب لا يزال قائما ، http.Get
الإصدار:
http.Response.Body
هو io.ReadCloser
تماما مثل http.Request.Body
.
func EncodeUrl(url, fn string) error {
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
cmd := exec.Command("ffmpeg", ......, fn)
cmd.Stdin = resp.Body
return cmd.Run()
}
//edit2:
هذا يجب أن العمل وفقا مارتيني الوثائق, ولكن مرة أخرى, أنا أوصي تعلم استخدام ServeMux أو على الأقل استخدام الغوريلا.
m := martini.Classic()
m.Get("/stream/:ytid", func(params martini.Params, rw http.ResponseWriter,
req *http.Request) string {
ytid := params["ytid"]
stream_link := exec.Command("youtube-dl","-f", "140", "-g", "https://www.youtube.com/watch?v=" + ytid)
var out bytes.Buffer
stream_link.Stdout = &out
errr := stream_link.Run()
if err != nil {
log.Fatal(err)
}
log.Println("Link", out.String())
cmd_ff := exec.Command("ffmpeg", "-i", "pipe:0", "-acodec", "libmp3lame", "-f", "mp3", "-")
resp, err := http.Get(url)
if err != nil {
log.Fatal(err)
}
cmd_ff.Stdin = resp.Body
go func() {
defer resp.Body.Close()
if err := cmd_ff.Run(); err != nil {
log.Fatal(err)
}
}()
return "Youtube ID: " + ytid
})
m.Run()