package main import ( "bytes" "context" "fmt" "io" "log" "net/http" "os/exec" "time" ) func compressRAMHandler(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "Только POST метод", http.StatusMethodNotAllowed) return } w.Header().Set("Content-Type", "video/mp4") w.Header().Set("Transfer-Encoding", "chunked") ctx, cancel := context.WithTimeout(r.Context(), 60*time.Second) defer cancel() args := []string{ "-y", "-analyzeduration", "10M", "-probesize", "10M", "-i", "pipe:0", "-c:v", "libx264", "-preset", "veryfast", "-crf", "28", "-threads", "4", "-movflags", "frag_keyframe+empty_moov", "-f", "mp4", "pipe:1", } cmd := exec.CommandContext(ctx, "ffmpeg", args...) cmd.Stdin = r.Body // Буфер для сбора ошибок FFmpeg var stderrBuf bytes.Buffer cmd.Stderr = &stderrBuf stdoutPipe, err := cmd.StdoutPipe() if err != nil { http.Error(w, fmt.Sprintf("Ошибка pipe stdout: %v", err), http.StatusInternalServerError) return } if err := cmd.Start(); err != nil { http.Error(w, fmt.Sprintf("Ошибка запуска FFmpeg: %v", err), http.StatusInternalServerError) return } _, _ = io.Copy(w, stdoutPipe) if waitErr := cmd.Wait(); waitErr != nil { log.Printf("FFmpeg завершился с ошибкой (%v):\n%s", waitErr, stderrBuf.String()) } } func main() { http.HandleFunc("/compress", compressRAMHandler) log.Println("RAM Converter запущен на :1554...") log.Fatal(http.ListenAndServe("127.0.0.1:1554", nil)) }