Last active
January 13, 2021 04:41
-
-
Save as/096e8e7bcf9da60e7f83367afec40b21 to your computer and use it in GitHub Desktop.
ffmpeg magic: piped mp4 output without fragments
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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