Skip to content

Commit

Permalink
HasVideo() generalized to HasStreams()
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexEidt committed Sep 15, 2022
1 parent 97e27bf commit 394eb7e
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 31 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ type Options struct {
Bitrate int // Bitrate.
Format string // Format of audio.
Codec string // Audio Codec.
Video string // File path for Video to use.
StreamFile string // File path for extra stream data.
}
```

The `Options.Video` parameter is intended for users who wish to alter an audio stream from a video. Instead of having to process the audio and store in a file and then combine with the video later, the user can simply pass in the original video file path via the `Options.Video` parameter. This will combine the audio with all other streams in the given video file (Video, Subtitle, Data, and Attachments Streams) and will cut all streams to be the same length. **Note that `aio` is not a audio/video editing library.**
The `Options.StreamFile` parameter is intended for users who wish to alter an audio stream from a video. Instead of having to process the audio and store in a file and then combine with the video later, the user can simply pass in the original video file path via the `Options.StreamFile` parameter. This will combine the audio with all other streams in the given video file (Video, Subtitle, Data, and Attachments Streams) and will cut all streams to be the same length. **Note that `aio` is not a audio/video editing library.**

Note that this means that adding extra stream data from a file will only work if the `filename` being written to is a container format, i.e attempting to add video streams to a `wav` file will result in a undefined behavior.

Expand Down Expand Up @@ -74,7 +74,7 @@ Total() int
Duration() float64
Format() string
Codec() string
HasVideo() bool
HasStreams() bool
Buffer() []byte
MetaData() map[string]string
Samples() interface{}
Expand All @@ -92,7 +92,7 @@ Close()
aio.NewAudioWriter(filename string, options *aio.Options) (*aio.AudioWriter, error)

FileName() string
Video() string
StreamFile() string
SampleRate() int
Channels() int
Bitrate() int
Expand Down Expand Up @@ -240,7 +240,7 @@ options := aio.Options{
Bitrate: audio.Bitrate(),
Format: audio.Format(),
Codec: "aac",
Video: "movie.mov",
StreamFile: "movie.mov",
}

writer, _ := aio.NewAudioWriter("output.mp4", &options)
Expand Down
1 change: 1 addition & 0 deletions aio_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ func TestAudioIO(t *testing.T) {
assertEquals(audio.Codec(), "mp3")
assertEquals(audio.BitsPerSample(), 16)
assertEquals(audio.Stream(), 0)
assertEquals(audio.HasStreams(), false)
assertEquals(len(audio.Buffer()), 0)

fmt.Println("Audio File IO test passed")
Expand Down
33 changes: 21 additions & 12 deletions audio.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ type Audio struct {
format string // Format of audio samples.
codec string // Codec used for video encoding.
ended bool // Flag storing whether Audio reading has ended.
hasvideo bool // Flag storing whether file contains Video.
hasstreams bool // Flag storing whether file has additional data streams.
buffer []byte // Raw audio data.
metadata map[string]string // Audio Metadata.
pipe *io.ReadCloser // Stdout pipe for ffmpeg process.
Expand Down Expand Up @@ -81,8 +81,9 @@ func (audio *Audio) Codec() string {
return audio.codec
}

func (audio *Audio) HasVideo() bool {
return audio.hasvideo
// Returns true if file has any video, subtitle, data or attachment streams.
func (audio *Audio) HasStreams() bool {
return audio.hasstreams
}

func (audio *Audio) Buffer() []byte {
Expand Down Expand Up @@ -165,20 +166,28 @@ func NewAudioStreams(filename string, options *Options) ([]*Audio, error) {

bps := int(parse(regexp.MustCompile(`\d{1,2}`).FindString(format))) // Bits per sample.

videoData, err := ffprobe(filename, "v")
if err != nil {
return nil, err
// Loop over all stream types. v: Video, s: Subtitle, d: Data, t: Attachments
hasstream := false
for _, c := range "vsdt" {
data, err := ffprobe(filename, string(c))
if err != nil {
return nil, err
}
if len(data) > 0 {
hasstream = true
break
}
}

streams := make([]*Audio, len(audioData))
for i, data := range audioData {
audio := &Audio{
filename: filename,
format: format,
bps: bps,
stream: i,
hasvideo: len(videoData) > 0,
metadata: data,
filename: filename,
format: format,
bps: bps,
stream: i,
hasstreams: hasstream,
metadata: data,
}

audio.addAudioData(data)
Expand Down
26 changes: 13 additions & 13 deletions audiowriter.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (

type AudioWriter struct {
filename string // Output filename.
video string // Extra stream data filename.
streamfile string // Extra stream data filename.
samplerate int // Audio Sample Rate in Hz.
channels int // Number of audio channels.
bitrate int // Bitrate for audio encoding.
Expand All @@ -26,8 +26,8 @@ func (writer *AudioWriter) FileName() string {
}

// File used to fill in extra stream data.
func (writer *AudioWriter) Video() string {
return writer.video
func (writer *AudioWriter) StreamFile() string {
return writer.streamfile
}

// Audio Sample Rate in Hz.
Expand Down Expand Up @@ -67,10 +67,10 @@ func NewAudioWriter(filename string, options *Options) (*AudioWriter, error) {
}

writer := &AudioWriter{
filename: filename,
video: options.Video,
bitrate: options.Bitrate,
codec: options.Codec,
filename: filename,
streamfile: options.StreamFile,
bitrate: options.Bitrate,
codec: options.Codec,
}

writer.samplerate = 44100 // 44100 Hz sampling rate by default.
Expand All @@ -92,11 +92,11 @@ func NewAudioWriter(filename string, options *Options) (*AudioWriter, error) {
}
}

if options.Video != "" {
if !exists(options.Video) {
return nil, fmt.Errorf("file %s does not exist", options.Video)
if options.StreamFile != "" {
if !exists(options.StreamFile) {
return nil, fmt.Errorf("file %s does not exist", options.StreamFile)
}
writer.video = options.Video
writer.streamfile = options.StreamFile
}

return writer, nil
Expand All @@ -119,10 +119,10 @@ func (writer *AudioWriter) init() error {
}

// Assumes "writer.file" is a container format.
if writer.video != "" {
if writer.streamfile != "" {
command = append(
command,
"-i", writer.video,
"-i", writer.streamfile,
"-map", "0:a:0",
"-map", "1:v?", // Add Video streams if present.
"-c:v", "copy",
Expand Down
2 changes: 1 addition & 1 deletion options.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ type Options struct {
Bitrate int // Bitrate.
Format string // Format of audio.
Codec string // Audio Codec.
Video string // File path for Video to use.
StreamFile string // File path for extra stream data.
}

0 comments on commit 394eb7e

Please sign in to comment.