Skip to content

Instantly share code, notes, and snippets.

@nadermx
Created November 7, 2022 02:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nadermx/6bc255e79e8fd5c32a092750005b2d03 to your computer and use it in GitHub Desktop.
Save nadermx/6bc255e79e8fd5c32a092750005b2d03 to your computer and use it in GitHub Desktop.
if currentEnv == prodEnv {
out, err := exec.Command("which", "youtube-dl").CombinedOutput()
if err != nil {
log.Printf("unable to autodetect youtube-dl path: %v\n", err)
} else {
YoutubeDLPath = string(bytes.TrimSpace(out))
}
}
func pipeThruFfmpegToMp4(vi *VideoInfo, rw web.ResponseWriter) error {
var ffmpeg *exec.Cmd
if vi.GetEndTime() == -1 {
if vi.GetStartTime() == 0 {
ffmpeg = exec.Command(
"ffmpeg",
"-thread_queue_size", "5120",
"-i", "-",
"-thread_queue_size", "5120",
"-i", "pipe:3",
"-c:v", "copy",
"-c:a", "copy",
"-movflags", "frag_keyframe+empty_moov+faststart", "-frag_duration", "3600",
"-f", "mp4",
"-")
} else {
ffmpeg = exec.Command(
"ffmpeg",
"-thread_queue_size", "5120",
"-i", "-",
"-ss", fmt.Sprintf("%.0f", vi.GetStartTime()),
"-thread_queue_size", "5120",
"-i", "pipe:3",
"-ss", fmt.Sprintf("%.0f", vi.GetStartTime()),
"-c:v", "copy",
"-c:a", "copy",
"-movflags", "frag_keyframe+empty_moov+faststart", "-frag_duration", "3600",
"-f", "mp4",
"-")
}
} else {
ffmpeg = exec.Command(
"ffmpeg",
"-thread_queue_size", "5120",
"-i", "-",
"-thread_queue_size", "5120",
"-i", "pipe:3",
"-ss", fmt.Sprintf("%.0f", vi.GetStartTime()),
"-to", fmt.Sprintf("%.0f", vi.GetEndTime()),
"-c:v", "copy",
"-c:a", "copy",
"-movflags", "frag_keyframe+empty_moov+faststart", "-frag_duration", "3600",
"-f", "mp4",
"-")
}
youtubedlvideo := exec.Command(YoutubeDLPath, "--verbose", "-c", "--no-part", "-f", fmt.Sprintf("%s/bestvideo[ext=mp4]/bestvideo/best", vi.GetFormat()), "--no-geo-bypass", "--no-cache-dir", "--hls-prefer-native", "-o", "-", fmt.Sprintf("%s", vi.GetVideoUrl()))
youtubedl := exec.Command(YoutubeDLPath, "--verbose", "-c", "--no-part", "-f", "bestaudio[ext=m4a]/bestaudio/best", "--no-geo-bypass", "--no-cache-dir", "--hls-prefer-native", "-o", "-", fmt.Sprintf("%s", vi.GetVideoUrl()))
youtubedl.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
youtubedlvideo.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
ffmpeg.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
var ytvbuf, ytbuf, ffbuf bytes.Buffer
youtubedlvideo.Stderr = &ytvbuf
youtubedl.Stderr = &ytbuf
ffmpeg.Stderr = &ffbuf
video, err := youtubedlvideo.StdoutPipe()
if err != nil {
log.Printf("pipeThruFfmpegToMp4: %v\n", err)
return err
}
pipe3, err := youtubedl.StdoutPipe()
if err != nil {
log.Printf("pipeThruFfmpegToMp4: %v\n", err)
return err
}
ffmpeg.Stdin = video
ffmpeg.ExtraFiles = []*os.File{pipe3.(*os.File)}
ffmpeg.Stdout = rw
ffmpegdir, err := ioutil.TempDir("", "ffmpegdirmp4")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(ffmpegdir) // clean up
youtubedldir, err := ioutil.TempDir("", "youtubedldirmp4")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(youtubedldir) // clean up
youtubedlvideodir, err := ioutil.TempDir("", "youtubedlvideodirmp4")
if err != nil {
log.Fatal(err)
}
defer os.RemoveAll(youtubedlvideodir) // clean up
ffmpeg.Dir = ffmpegdir
youtubedl.Dir = youtubedldir
youtubedlvideo.Dir = youtubedlvideodir
// Headers sent, no turning back now
rw.Header().Set("Content-Type", "video/mp4")
rw.Header().Set("Content-Disposition", fmt.Sprintf("attachment;filename=\"%s.mp4\"", vi.GetSlug()))
rw.Flush()
ffmpeg.Start()
youtubedlvideo.Start()
youtubedl.Start()
ffmpeg.Wait()
syscall.Kill(-youtubedl.Process.Pid, syscall.SIGKILL)
syscall.Kill(-youtubedlvideo.Process.Pid, syscall.SIGKILL)
syscall.Kill(-ffmpeg.Process.Pid, syscall.SIGKILL)
youtubedlvideo.Wait()
youtubedl.Wait()
// check ytvbuf, ytbuf, ffbuf for stderr errors
if ffbuf.Len() != 0 {
rollbar.Error(rollbar.ERR, err, &rollbar.Field{"stderr", ffbuf.String()})
log.Printf("pipeThruFfmpegToMp4: %v\n", ffbuf.String())
}
if ytvbuf.Len() != 0 {
rollbar.Error(rollbar.ERR, err, &rollbar.Field{"stderr", ytvbuf.String()})
log.Printf("pipeThruYouTubeDLToMp4: %v\n", ytvbuf.String())
}
if ytbuf.Len() != 0 {
rollbar.Error(rollbar.ERR, err, &rollbar.Field{"stderr", ytbuf.String()})
log.Printf("pipeThruYouTubeDLToMp4: %v\n", ytbuf.String())
}
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment