Skip to content

Commit 0bce47c

Browse files
committed
HasAudio() generalized to HasStreams()
1 parent bbbb230 commit 0bce47c

File tree

4 files changed

+72
-62
lines changed

4 files changed

+72
-62
lines changed

README.md

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ Stream() int
3232
Duration() float64
3333
FPS() float64
3434
Codec() string
35-
HasAudio() bool
35+
HasStreams() bool
3636
FrameBuffer() []byte
3737
MetaData() map[string]string
3838
SetFrameBuffer(buffer []byte) error
@@ -45,7 +45,7 @@ If all frames have been read, `video` will be closed automatically. If not all f
4545

4646
## `Camera`
4747

48-
The `Camera` can read from any cameras on the device running Vidio. It takes in the stream index. On most machines the webcam device has index 0.
48+
The `Camera` can read from any cameras on the device running `Vidio`. It takes in the stream index. On most machines the webcam device has index 0.
4949

5050
```go
5151
vidio.NewCamera(stream int) (*vidio.Camera, error)
@@ -71,7 +71,7 @@ The `VideoWriter` is used to write frames to a video file. The only required par
7171
vidio.NewVideoWriter(filename string, width, height int, options *vidio.Options) (*vidio.VideoWriter, error)
7272

7373
FileName() string
74-
Audio() string
74+
StreamFile() string
7575
Width() int
7676
Height() int
7777
Bitrate() int
@@ -89,25 +89,25 @@ Close()
8989

9090
```go
9191
type Options struct {
92-
Bitrate int // Bitrate.
93-
Loop int // For GIFs only. -1=no loop, 0=infinite loop, >0=number of loops.
94-
Delay int // Delay for final frame of GIFs.
95-
Macro int // Macroblock size for determining how to resize frames for codecs.
96-
FPS float64 // Frames per second for output video.
97-
Quality float64 // If bitrate not given, use quality instead. Must be between 0 and 1. 0:best, 1:worst.
98-
Codec string // Codec for video.
99-
Format string // Pixel Format for video. Default "rgb24".
100-
Audio string // File path for extra stream data.
92+
Bitrate int // Bitrate.
93+
Loop int // For GIFs only. -1=no loop, 0=infinite loop, >0=number of loops.
94+
Delay int // Delay for final frame of GIFs.
95+
Macro int // Macroblock size for determining how to resize frames for codecs.
96+
FPS float64 // Frames per second for output video.
97+
Quality float64 // If bitrate not given, use quality instead. Must be between 0 and 1. 0:best, 1:worst.
98+
Codec string // Codec for video.
99+
Format string // Pixel Format for video. Default "rgb24".
100+
StreamFile string // File path for extra stream data.
101101
}
102102
```
103103

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

106-
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.
106+
This means that adding extra stream data from a file will only work if the filename being written to is a container format.
107107

108108
## Images
109109

110-
Vidio provides some convenience functions for reading and writing to images using an array of bytes. Currently, only `png` and `jpeg` formats are supported. When reading images, an optional `buffer` can be passed in to avoid array reallocation.
110+
`Vidio` provides some convenience functions for reading and writing to images using an array of bytes. Currently, only `png` and `jpeg` formats are supported. When reading images, an optional `buffer` can be passed in to avoid array reallocation.
111111

112112
```go
113113
Read(filename string, buffer ...[]byte) (int, int, []byte, error)
@@ -124,8 +124,8 @@ options := vidio.Options{
124124
FPS: video.FPS(),
125125
Bitrate: video.Bitrate(),
126126
}
127-
if video.HasAudio() {
128-
options.Audio = video.FileName()
127+
if video.HasStreams() {
128+
options.StreamFile = video.FileName()
129129
}
130130

131131
writer, _ := vidio.NewVideoWriter("output.mp4", video.Width(), video.Height(), &options)

video.go

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ type Video struct {
2121
duration float64 // Duration of video in seconds.
2222
fps float64 // Frames per second.
2323
codec string // Codec used for video encoding.
24-
hasaudio bool // Flag storing whether file has Audio.
24+
hasstreams bool // Flag storing whether file has additional data streams.
2525
framebuffer []byte // Raw frame data.
2626
metadata map[string]string // Video metadata.
2727
pipe *io.ReadCloser // Stdout pipe for ffmpeg process.
@@ -72,8 +72,9 @@ func (video *Video) Codec() string {
7272
return video.codec
7373
}
7474

75-
func (video *Video) HasAudio() bool {
76-
return video.hasaudio
75+
// Returns true if file has any audio, subtitle, data or attachment streams.
76+
func (video *Video) HasStreams() bool {
77+
return video.hasstreams
7778
}
7879

7980
func (video *Video) FrameBuffer() []byte {
@@ -125,19 +126,27 @@ func NewVideoStreams(filename string) ([]*Video, error) {
125126
return nil, fmt.Errorf("no video data found in %s", filename)
126127
}
127128

128-
audioData, err := ffprobe(filename, "a")
129-
if err != nil {
130-
return nil, err
129+
// Loop over all stream types. a: Audio, s: Subtitle, d: Data, t: Attachments
130+
hasstream := false
131+
for _, c := range "asdt" {
132+
data, err := ffprobe(filename, string(c))
133+
if err != nil {
134+
return nil, err
135+
}
136+
if len(data) > 0 {
137+
hasstream = true
138+
break
139+
}
131140
}
132141

133142
streams := make([]*Video, len(videoData))
134143
for i, data := range videoData {
135144
video := &Video{
136-
filename: filename,
137-
depth: 3,
138-
stream: i,
139-
hasaudio: len(audioData) > 0,
140-
metadata: data,
145+
filename: filename,
146+
depth: 3,
147+
stream: i,
148+
hasstreams: hasstream,
149+
metadata: data,
141150
}
142151

143152
video.addVideoData(data)

videowriter.go

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -12,42 +12,42 @@ import (
1212
)
1313

1414
type VideoWriter struct {
15-
filename string // Output filename.
16-
audio string // Extra stream data filename.
17-
width int // Frame width.
18-
height int // Frame height.
19-
bitrate int // Output video bitrate.
20-
loop int // Number of times for GIF to loop.
21-
delay int // Delay of final frame of GIF. Default -1 (same delay as previous frame).
22-
macro int // Macroblock size for determining how to resize frames for codecs.
23-
fps float64 // Frames per second for output video. Default 25.
24-
quality float64 // Used if bitrate not given. Default 0.5.
25-
codec string // Codec to encode video with. Default libx264.
26-
format string // Output format. Default rgb24.
27-
pipe *io.WriteCloser // Stdout pipe of ffmpeg process.
28-
cmd *exec.Cmd // ffmpeg command.
15+
filename string // Output filename.
16+
streamfile string // Extra stream data filename.
17+
width int // Frame width.
18+
height int // Frame height.
19+
bitrate int // Output video bitrate.
20+
loop int // Number of times for GIF to loop.
21+
delay int // Delay of final frame of GIF. Default -1 (same delay as previous frame).
22+
macro int // Macroblock size for determining how to resize frames for codecs.
23+
fps float64 // Frames per second for output video. Default 25.
24+
quality float64 // Used if bitrate not given. Default 0.5.
25+
codec string // Codec to encode video with. Default libx264.
26+
format string // Output format. Default rgb24.
27+
pipe *io.WriteCloser // Stdout pipe of ffmpeg process.
28+
cmd *exec.Cmd // ffmpeg command.
2929
}
3030

3131
// Optional parameters for VideoWriter.
3232
type Options struct {
33-
Bitrate int // Bitrate.
34-
Loop int // For GIFs only. -1=no loop, 0=infinite loop, >0=number of loops.
35-
Delay int // Delay for final frame of GIFs.
36-
Macro int // Macroblock size for determining how to resize frames for codecs.
37-
FPS float64 // Frames per second for output video.
38-
Quality float64 // If bitrate not given, use quality instead. Must be between 0 and 1. 0:best, 1:worst.
39-
Codec string // Codec for video.
40-
Format string // Pixel Format for video. Default "rgb24".
41-
Audio string // File path for extra stream data.
33+
Bitrate int // Bitrate.
34+
Loop int // For GIFs only. -1=no loop, 0=infinite loop, >0=number of loops.
35+
Delay int // Delay for final frame of GIFs.
36+
Macro int // Macroblock size for determining how to resize frames for codecs.
37+
FPS float64 // Frames per second for output video.
38+
Quality float64 // If bitrate not given, use quality instead. Must be between 0 and 1. 0:best, 1:worst.
39+
Codec string // Codec for video.
40+
Format string // Pixel Format for video. Default "rgb24".
41+
StreamFile string // File path for extra stream data.
4242
}
4343

4444
func (writer *VideoWriter) FileName() string {
4545
return writer.filename
4646
}
4747

4848
// File used to fill in extra stream data.
49-
func (writer *VideoWriter) Audio() string {
50-
return writer.audio
49+
func (writer *VideoWriter) StreamFile() string {
50+
return writer.streamfile
5151
}
5252

5353
func (writer *VideoWriter) Width() int {
@@ -155,11 +155,11 @@ func NewVideoWriter(filename string, width, height int, options *Options) (*Vide
155155
writer.format = options.Format
156156
}
157157

158-
if options.Audio != "" {
159-
if !exists(options.Audio) {
160-
return nil, fmt.Errorf("file %s does not exist", options.Audio)
158+
if options.StreamFile != "" {
159+
if !exists(options.StreamFile) {
160+
return nil, fmt.Errorf("file %s does not exist", options.StreamFile)
161161
}
162-
writer.audio = options.Audio
162+
writer.streamfile = options.StreamFile
163163
}
164164

165165
return writer, nil
@@ -184,12 +184,12 @@ func (writer *VideoWriter) init() error {
184184

185185
gif := strings.HasSuffix(strings.ToLower(writer.filename), ".gif")
186186

187-
// Assumes "writer.file" is a container format.
187+
// Assumes "writer.streamfile" is a container format.
188188
// gif check is included since they are a common format.
189-
if writer.audio != "" && !gif {
189+
if writer.streamfile != "" && !gif {
190190
command = append(
191191
command,
192-
"-i", writer.audio,
192+
"-i", writer.streamfile,
193193
"-map", "0:v:0",
194194
"-map", "1:a?", // Add Audio streams if present.
195195
"-c:a", "copy",

vidio_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ func TestVideoMetaData(t *testing.T) {
4646
assertEquals(video.fps, float64(30))
4747
assertEquals(video.codec, "h264")
4848
assertEquals(video.stream, 0)
49+
assertEquals(video.hasstreams, true)
4950
assertEquals(len(video.framebuffer), 0)
5051

5152
if video.pipe != nil {
@@ -92,8 +93,8 @@ func TestVideoWriting(t *testing.T) {
9293
Bitrate: video.Bitrate(),
9394
Codec: video.Codec(),
9495
}
95-
if video.HasAudio() {
96-
options.Audio = video.FileName()
96+
if video.HasStreams() {
97+
options.StreamFile = video.FileName()
9798
}
9899

99100
writer, err := NewVideoWriter(output, video.width, video.height, &options)

0 commit comments

Comments
 (0)