Skip to content

Instantly share code, notes, and snippets.

@as
Last active January 13, 2021 04:41
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 as/096e8e7bcf9da60e7f83367afec40b21 to your computer and use it in GitHub Desktop.
Save as/096e8e7bcf9da60e7f83367afec40b21 to your computer and use it in GitHub Desktop.
ffmpeg magic: piped mp4 output without fragments
func ffmpeg(in io.Reader) (out io.ReadCloser) {
// the command overwrites the output file that "already exists"
// actually, the output file is a reference to ffmpegs own file descriptor #3
c := exec.Command("ffmpeg", "-y", "-i", "-", "-c", "copy", "-f", "mp4", "/proc/self/fd/3")
// standard input, buffered by us
c.Stdin = bufio.NewReader(in)
// create a memory backed temporary file using the MemfdCreate syscall
// the file is managed by the kernel and doesn't need to be deleted
tmp := ramTMP()
// seek to the start, just in case, after the command is finished
defer tmp.Seek(0, 0)
// extrafiles makes ffmpeg inherit the given file descriptors, starting at 3 onward
c.ExtraFiles = append(c.ExtraFiles, tmp)
// run it, ffmpeg will open its own file descriptor, which is seekable (unlike pipe:3)
c.Run()
// return the memory backed file, which the caller will close after reading
return tmp
}
func ramTMP() *os.File {
// names need not be unique here, they have no meaning except for debugging in procfs
fd, err := unix.MemfdCreate("tmp", os.O_RDWR)
if err != nil {
panic(err)
}
return os.NewFile(uintptr(fd), "tmp")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment