From b07339a04c8ef8b91094a9e52d0b946d5ba0852e Mon Sep 17 00:00:00 2001 From: Alex Eidt Date: Fri, 8 Apr 2022 15:26:09 -0700 Subject: [PATCH] Check audio files for audio track --- utils.go | 40 ++++++++++++++++++++++++++++++++++++++++ video.go | 44 +++----------------------------------------- videowriter.go | 7 ++++++- 3 files changed, 49 insertions(+), 42 deletions(-) diff --git a/utils.go b/utils.go index 3e2af58..a0ec794 100644 --- a/utils.go +++ b/utils.go @@ -2,6 +2,7 @@ package vidio import ( "errors" + "io" "os" "os/exec" "regexp" @@ -34,6 +35,45 @@ func checkExists(program string) { } } +// Runs ffprobe on the given file and returns a map of the metadata. +func ffprobe(filename, stype string) map[string]string { + // "stype" is stream stype. "v" for video, "a" for audio. + // Extract video information with ffprobe. + cmd := exec.Command( + "ffprobe", + "-show_streams", + "-select_streams", stype, // Only show video data + "-print_format", "compact", + "-loglevel", "quiet", + filename, + ) + + pipe, err := cmd.StdoutPipe() + if err != nil { + panic(err) + } + + if err := cmd.Start(); err != nil { + panic(err) + } + // Read ffprobe output from Stdout. + buffer := make([]byte, 2<<10) + total := 0 + for { + n, err := pipe.Read(buffer[total:]) + total += n + if err == io.EOF { + break + } + } + // Wait for ffprobe command to complete. + if err := cmd.Wait(); err != nil { + panic(err) + } + + return parseFFprobe(buffer[:total]) +} + // Parse ffprobe output to fill in video data. func parseFFprobe(input []byte) map[string]string { data := make(map[string]string) diff --git a/video.go b/video.go index b89925a..0b03177 100644 --- a/video.go +++ b/video.go @@ -29,52 +29,14 @@ type Video struct { // Uses ffprobe to get video information and fills in the Video struct with this data. func NewVideo(filename string) *Video { if !exists(filename) { - panic("File: " + filename + " does not exist") + panic("Video file " + filename + " does not exist") } // Check if ffmpeg and ffprobe are installed on the users machine. checkExists("ffmpeg") checkExists("ffprobe") - ffprobe := func(stype string) map[string]string { - // "stype" is stream stype. "v" for video, "a" for audio. - // Extract video information with ffprobe. - cmd := exec.Command( - "ffprobe", - "-show_streams", - "-select_streams", stype, // Only show video data - "-print_format", "compact", - "-loglevel", "quiet", - filename, - ) - - pipe, err := cmd.StdoutPipe() - if err != nil { - panic(err) - } - - if err := cmd.Start(); err != nil { - panic(err) - } - // Read ffprobe output from Stdout. - buffer := make([]byte, 2<<10) - total := 0 - for { - n, err := pipe.Read(buffer[total:]) - total += n - if err == io.EOF { - break - } - } - // Wait for ffprobe command to complete. - if err := cmd.Wait(); err != nil { - panic(err) - } - - return parseFFprobe(buffer[:total]) - } - - videoData := ffprobe("v") - audioData := ffprobe("a") + videoData := ffprobe(filename, "v") + audioData := ffprobe(filename, "a") video := &Video{filename: filename, depth: 3} diff --git a/videowriter.go b/videowriter.go index 62edf40..3c8ebf1 100644 --- a/videowriter.go +++ b/videowriter.go @@ -93,8 +93,13 @@ func NewVideoWriter(filename string, width, height int, options *Options) *Video if options.audio != "" { if !exists(options.audio) { - panic("Audio file does not exist.") + panic("Audio file " + options.audio + " does not exist.") } + + if len(ffprobe(options.audio, "a")) == 0 { + panic("Given \"audio\" file " + options.audio + " has no audio.") + } + writer.audio = options.audio if options.audio_codec == "" {