@@ -2,30 +2,231 @@ package media
2
2
3
3
import (
4
4
"context"
5
- "net/url "
6
- "strings "
5
+ "io "
6
+ "time "
7
7
)
8
8
9
9
////////////////////////////////////////////////////////////////////////////////
10
10
// TYPES
11
11
12
- type (
13
- MediaKey string
14
- MediaFlag uint64
15
- DecodeIteratorFunc func (context.Context , MediaPacket ) error
16
- )
12
+ // MediaFlag is a bitfield of flags for media, including type of media
13
+ type MediaFlag uint
14
+
15
+ // MediaKey is a string which is used for media metadata
16
+ type MediaKey string
17
+
18
+ // Demux is a function which is called for each packet in the media, which
19
+ // is associated with a single stream. The function should return an error if
20
+ // the decode should be terminated.
21
+ type DemuxFn func (context.Context , Packet ) error
22
+
23
+ // DecodeFn is a function which is called for each frame in the media, which
24
+ // is associated with a single stream. The function should return an error if
25
+ // the decode should be terminated.
26
+ type DecodeFn func (context.Context , Frame ) error
17
27
18
28
////////////////////////////////////////////////////////////////////////////////
19
29
// INTERFACES
20
30
21
- // Media represents either input or output media
31
+ // Manager is an interface to the ffmpeg media library for media manipulation
32
+ type Manager interface {
33
+ io.Closer
34
+
35
+ // Enumerate formats with MEDIA_FLAG_ENCODER, MEDIA_FLAG_DECODER,
36
+ // MEDIA_FLAG_FILE and MEDIA_FLAG_DEVICE flags to filter.
37
+ // Lookups can be further filtered by name, mimetype and extension
38
+ MediaFormats (MediaFlag , ... string ) []MediaFormat
39
+
40
+ // Open media file for reading and return it. A format can be specified
41
+ // to "force" a specific format
42
+ OpenFile (string , MediaFormat ) (Media , error )
43
+
44
+ // Open media URL for reading and return it. A format can be specified
45
+ // to "force" a specific format
46
+ OpenURL (string , MediaFormat ) (Media , error )
47
+
48
+ // Open media device with a specific name for reading and return it.
49
+ OpenDevice (string ) (Media , error )
50
+
51
+ // Create file for writing and return it
52
+ CreateFile (string ) (Media , error )
53
+
54
+ // Create an output device with a specific name for writing and return it
55
+ CreateDevice (string ) (Media , error )
56
+
57
+ // Create a map of input media. If MediaFlag is MEDIA_FLAG_NONE, then
58
+ // all audio, video and subtitle streams are mapped, or else a
59
+ // combination of MEDIA_FLAG_AUDIO,
60
+ // MEDIA_FLAG_VIDEO, MEDIA_FLAG_SUBTITLE and MEDIA_FLAG_DATA
61
+ // can be used to map specific types of streams.
62
+ Map (Media , MediaFlag ) (Map , error )
63
+
64
+ // Demux a media file, passing packets to a callback function
65
+ Demux (context.Context , Map , DemuxFn ) error
66
+
67
+ // Decode a packet into a series of frames, passing decoded frames to
68
+ // a callback function
69
+ Decode (context.Context , Map , Packet , DecodeFn ) error
70
+
71
+ // Log messages from ffmpeg
72
+ SetDebug (bool )
73
+ }
74
+
75
+ // MediaFormat is an input or output format for media items
76
+ type MediaFormat interface {
77
+ // Return the names of the media format
78
+ Name () []string
79
+
80
+ // Return a longer description of the media format
81
+ Description () string
82
+
83
+ // Return MEDIA_FLAG_ENCODER, MEDIA_FLAG_DECODER, MEDIA_FLAG_FILE
84
+ // and MEDIA_FLAG_DEVICE flags
85
+ Flags () MediaFlag
86
+
87
+ // Return mimetypes handled
88
+ MimeType () []string
89
+
90
+ // Return file extensions handled
91
+ Ext () []string
92
+
93
+ // Return the default audio codec for the format
94
+ DefaultAudioCodec () Codec
95
+
96
+ // Return the default video codec for the format
97
+ DefaultVideoCodec () Codec
98
+
99
+ // Return the default subtitle codec for the format
100
+ DefaultSubtitleCodec () Codec
101
+ }
102
+
103
+ // Map is a mapping of input media, potentially to output media
104
+ type Map interface {
105
+ // Return input media
106
+ Input () Media
107
+
108
+ // Return a single stream which is mapped for decoding, filtering by
109
+ // stream type. Returns nil if there is no selection of that type
110
+ Streams (MediaFlag ) []Stream
111
+
112
+ // Print a summary of the mapping
113
+ PrintMap (w io.Writer )
114
+
115
+ // Resample an audio stream
116
+ Resample (AudioFormat , Stream ) error
117
+
118
+ // Encode to output media using default codec from a specific stream
119
+ //Encode(Media, Stream) error
120
+ }
121
+
122
+ // Media is a source or destination of media
22
123
type Media interface {
23
- URL () * url.URL // Return URL for the media location
24
- Flags () MediaFlag // Return flags
124
+ io.Closer
125
+
126
+ // URL for the media
127
+ URL () string
128
+
129
+ // Return enumeration of streams
130
+ Streams () []Stream
131
+
132
+ // Return media flags for the media
133
+ Flags () MediaFlag
134
+
135
+ // Return the format of the media
136
+ Format () MediaFormat
137
+
138
+ // Return metadata for the media
139
+ Metadata () Metadata
140
+
141
+ // Set metadata value by key, or remove it if the value is nil
142
+ Set (MediaKey , any ) error
143
+ }
144
+
145
+ // Stream of data multiplexed in the media
146
+ type Stream interface {
147
+ // Return index of stream in the media
148
+ Index () int
149
+
150
+ // Return media flags for the stream
151
+ Flags () MediaFlag
152
+
153
+ // Return artwork for the stream - if MEDIA_FLAG_ARTWORK is set
154
+ Artwork () []byte
155
+ }
156
+
157
+ // Metadata embedded in the media
158
+ type Metadata interface {
159
+ // Return enumeration of keys
160
+ Keys () []MediaKey
161
+
162
+ // Return value for key
163
+ Value (MediaKey ) any
164
+ }
165
+
166
+ // Packet is a single unit of data in the media
167
+ type Packet interface {
168
+ // Flags returns the flags for the packet from the stream
169
+ Flags () MediaFlag
170
+
171
+ // Stream returns the stream which the packet belongs to
172
+ Stream () Stream
173
+
174
+ // IsKeyFrame returns true if the packet contains a key frame
175
+ IsKeyFrame () bool
176
+
177
+ // Pos returns the byte position of the packet in the media
178
+ Pos () int64
179
+
180
+ // Duration returns the duration of the packet
181
+ Duration () time.Duration
182
+
183
+ // Size of the packet in bytes
184
+ Size () int
185
+
186
+ // Bytes returns the raw bytes of the packet
187
+ Bytes () []byte
188
+ }
189
+
190
+ // Frame is a decoded video or audio frame
191
+ type Frame interface {
192
+ AudioFrame
193
+ VideoFrame
194
+
195
+ // Returns MEDIA_FLAG_VIDEO, MEDIA_FLAG_AUDIO
196
+ Flags () MediaFlag
197
+
198
+ // Returns true if planar format
199
+ //IsPlanar() bool
200
+
201
+ // Returns the samples for a specified channel, as array of bytes. For packed
202
+ // audio format, the channel should be 0.
203
+ //Bytes(channel int) []byte
25
204
}
26
205
27
- // MediaCodec is the codec and parameters
28
- type MediaCodec interface {
206
+ type AudioFrame interface {
207
+ // Returns the audio format, if MEDIA_FLAG_AUDIO is set
208
+ AudioFormat () AudioFormat
209
+
210
+ // Number of samples, if MEDIA_FLAG_AUDIO is set
211
+ NumSamples () int
212
+
213
+ // Audio channels, if MEDIA_FLAG_AUDIO is set
214
+ Channels () []AudioChannel
215
+
216
+ // Duration of the frame, if MEDIA_FLAG_AUDIO is set
217
+ Duration () time.Duration
218
+ }
219
+
220
+ type VideoFrame interface {
221
+ // Returns the audio format, if MEDIA_FLAG_VIDEO is set
222
+ PixelFormat () PixelFormat
223
+
224
+ // Return frame width and height, if MEDIA_FLAG_VIDEO is set
225
+ Size () (int , int )
226
+ }
227
+
228
+ // Codec is an encoder or decoder for a specific media type
229
+ type Codec interface {
29
230
// Name returns the unique name for the codec
30
231
Name () string
31
232
@@ -36,23 +237,17 @@ type MediaCodec interface {
36
237
Flags () MediaFlag
37
238
}
38
239
39
- // MediaPacket is a packet of data from a stream
40
- type MediaPacket interface {
41
- Size () int
42
- Bytes () []byte
43
- Stream () int
44
- }
45
-
46
240
////////////////////////////////////////////////////////////////////////////////
47
241
// CONSTANTS
48
242
49
243
const (
50
244
MEDIA_FLAG_ALBUM MediaFlag = (1 << iota ) // Is part of an album
51
245
MEDIA_FLAG_ALBUM_TRACK // Is an album track
52
- MEDIA_FLAG_ALBUM_COMPILATION // Album is a compliation
246
+ MEDIA_FLAG_ALBUM_COMPILATION // Album is a compilation
53
247
MEDIA_FLAG_TVSHOW // Is part of a TV Show
54
248
MEDIA_FLAG_TVSHOW_EPISODE // Is a TV Show episode
55
249
MEDIA_FLAG_FILE // Is a file
250
+ MEDIA_FLAG_DEVICE // Is a device
56
251
MEDIA_FLAG_VIDEO // Contains video
57
252
MEDIA_FLAG_AUDIO // Contains audio
58
253
MEDIA_FLAG_SUBTITLE // Contains subtitles
@@ -63,7 +258,6 @@ const (
63
258
MEDIA_FLAG_ENCODER // Is an encoder
64
259
MEDIA_FLAG_DECODER // Is an decoder
65
260
MEDIA_FLAG_NONE MediaFlag = 0
66
- MEDIA_FLAG_MIN = MEDIA_FLAG_ALBUM
67
261
MEDIA_FLAG_MAX = MEDIA_FLAG_DECODER
68
262
)
69
263
@@ -78,7 +272,7 @@ const (
78
272
MEDIA_KEY_COMPOSER MediaKey = "composer" // string
79
273
MEDIA_KEY_COPYRIGHT MediaKey = "copyright" // string
80
274
MEDIA_KEY_YEAR MediaKey = "date" // uint
81
- MEDIA_KEY_DISC MediaKey = "disc" // uint
275
+ MEDIA_KEY_DISC MediaKey = "disc" // uint xx or xx/yy
82
276
MEDIA_KEY_ENCODED_BY MediaKey = "encoded_by" // string
83
277
MEDIA_KEY_FILENAME MediaKey = "filename" // string
84
278
MEDIA_KEY_GENRE MediaKey = "genre" // string
@@ -88,7 +282,7 @@ const (
88
282
MEDIA_KEY_SERVICE_NAME MediaKey = "service_name" // string
89
283
MEDIA_KEY_SERVICE_PROVIDER MediaKey = "service_provider" // string
90
284
MEDIA_KEY_TITLE MediaKey = "title" // string
91
- MEDIA_KEY_TRACK MediaKey = "track" // uint
285
+ MEDIA_KEY_TRACK MediaKey = "track" // uint xx or xx/yy
92
286
MEDIA_KEY_VERSION_MAJOR MediaKey = "major_version" // string
93
287
MEDIA_KEY_VERSION_MINOR MediaKey = "minor_version" // string
94
288
MEDIA_KEY_SHOW MediaKey = "show" // string
@@ -116,12 +310,12 @@ func (f MediaFlag) String() string {
116
310
return f .FlagString ()
117
311
}
118
312
str := ""
119
- for v := MEDIA_FLAG_MIN ; v <= MEDIA_FLAG_MAX ; v <<= 1 {
313
+ for v := MediaFlag ( 1 ) ; v <= MEDIA_FLAG_MAX ; v <<= 1 {
120
314
if f & v == v {
121
- str += v .FlagString () + "|"
315
+ str += "|" + v .FlagString ()
122
316
}
123
317
}
124
- return strings . TrimSuffix ( str , "|" )
318
+ return str [ 1 :]
125
319
}
126
320
127
321
func (f MediaFlag ) FlagString () string {
@@ -140,6 +334,8 @@ func (f MediaFlag) FlagString() string {
140
334
return "MEDIA_FLAG_TVSHOW_EPISODE"
141
335
case MEDIA_FLAG_FILE :
142
336
return "MEDIA_FLAG_FILE"
337
+ case MEDIA_FLAG_DEVICE :
338
+ return "MEDIA_FLAG_DEVICE"
143
339
case MEDIA_FLAG_VIDEO :
144
340
return "MEDIA_FLAG_VIDEO"
145
341
case MEDIA_FLAG_AUDIO :
0 commit comments