-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathmedia.go
343 lines (287 loc) · 11.2 KB
/
media.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
package gopi
import (
"context"
"image"
"io"
"net/url"
"strings"
)
/*
This file contains definitions for media devices:
* Video and Audio encoding and decoding
* Input and output media devices
* DVB tuning and decoding (experimental)
There are aditional interfaces for audio and graphics elsewhere
*/
////////////////////////////////////////////////////////////////////////////////
// TYPES
type (
MediaKey string
MediaFlag uint64
DecodeIteratorFunc func(MediaDecodeContext, MediaPacket) error
DecodeFrameIteratorFunc func(MediaFrame) error
)
////////////////////////////////////////////////////////////////////////////////
// MEDIA MANAGER
// MediaManager for media file management
type MediaManager interface {
// OpenFile opens a local media file
OpenFile(path string) (MediaInput, error)
// OpenURL opens a network-based stream
OpenURL(url *url.URL) (MediaInput, error)
// CreateFile creates a local media file for output
CreateFile(path string) (MediaOutput, error)
// Close will release resources and close a media object
Close(Media) error
// ListCodecs enumerates codecs for a specific name and/or
// audio, video, encode and decode. By default (empty name and
// MediaFlag) lists all codecs
ListCodecs(string, MediaFlag) []MediaCodec
// Create an audio profile with format, sample rate, channels and layout
AudioProfile(AudioFormat, uint, AudioChannelLayout) MediaProfile
}
////////////////////////////////////////////////////////////////////////////////
// MEDIA OBJECTS
// Media is an input or output
type Media interface {
URL() *url.URL // Return URL for the media location
Metadata() MediaMetadata // Return metadata
Flags() MediaFlag // Return flags
Streams() []MediaStream // Return streams
StreamForIndex(int) MediaStream // Return stream by index
}
// MediaInput represents a source of media
type MediaInput interface {
Media
// StreamsForFlag returns array of stream indexes for
// the best streams to use according to the flags
StreamsForFlag(MediaFlag) []int
// Read loops over selected streams from media object, and
// packets are provided to a Decode function
Read(context.Context, []int, DecodeIteratorFunc) error
// DecodeFrameIterator loops over data packets from media stream
DecodeFrameIterator(MediaDecodeContext, MediaPacket, DecodeFrameIteratorFunc) error
}
// MediaOutput represents a sink for media
type MediaOutput interface {
Media
// Write packets to output
Write(MediaDecodeContext, MediaPacket) error
}
////////////////////////////////////////////////////////////////////////////////
// MEDIA PROFILES
type MediaProfile interface {
Flags() MediaFlag // Return audio or video profile
}
type MediaAudioProfile interface {
MediaProfile
Format() AudioFormat
SampleRate() uint
Layout() AudioChannelLayout
}
type MediaVideoProfile interface {
MediaProfile
}
////////////////////////////////////////////////////////////////////////////////
// MEDIA METADATA AND CODECS
// MediaMetadata are key value pairs for a media object
type MediaMetadata interface {
Keys() []MediaKey // Return all existing keys
Value(MediaKey) interface{} // Return value for key, or nil
}
// MediaCodec is the codec and parameters
type MediaCodec interface {
// Name returns the unique name for the codec
Name() string
// Description returns the long description for the codec
Description() string
// Flags for the codec (Audio, Video, Encoder, Decoder)
Flags() MediaFlag
}
////////////////////////////////////////////////////////////////////////////////
// MEDIA STREAMS, PACKETS AND FRAMES
// MediaStream is a stream of packets from a media object, with a defined
// codec and audio or video profile
type MediaStream interface {
Index() int // Stream index
Flags() MediaFlag // Flags for the stream (Audio, Video, etc)
Codec() MediaCodec // Return codec and parameters
Profile() MediaProfile // Return audio or video profile for stream
}
// MediaPacket is a packet of data from a stream
type MediaPacket interface {
Size() int
Bytes() []byte
Stream() int
}
// MediaFrame is a decoded audio or video frame
type MediaFrame interface {
// Implements image interface which can be saved to save frame as bitmap
image.Image
// Resample a frame to a specific profile
Resample(MediaProfile) (MediaFrame, error)
// Flags for the frame (Audio, Video)
Flags() MediaFlag
}
////////////////////////////////////////////////////////////////////////////////
// MEDIA ENCODING AND DECODING
// MediaDecodeContext provides packet data and streams for decoding
// frames of data
type MediaDecodeContext interface {
Stream() MediaStream // Origin of the packet
Frame() int // Frame counter
}
////////////////////////////////////////////////////////////////////////////////
// DVB INTERFACES - EXPERIMENTAL
// DVBManager encapsulates methods for DVB reception
type DVBManager interface {
// Tuners returns all tuners
Tuners() []DVBTuner
// ParseTunerParams returns a list of tuner parameters
ParseTunerParams(r io.Reader) ([]DVBTunerParams, error)
// Tune to parameters with context, which can be used to cancel
// or timeout the tuning process
Tune(context.Context, DVBTuner, DVBTunerParams, DVBTuneCallack) error
// Close tuner
Close(DVBTuner) error
}
// DVBTunerCallack is called when tuning has completed, so that
// set-up can begin
type DVBTuneCallack func(DVBContext)
// DVBTuneContext represents information obtained during the tuning
// process
type DVBContext interface {
// Services() []DVBService
}
// DVBTunerParams represents tune parameters
type DVBTunerParams interface {
// Name returns name for tune parameters
Name() string
}
// DVBTuner represents a tuning device, some hardware
// comtains more than one tuner. Each is represented by
// a unique identifier
type DVBTuner interface {
// Return tuner identifier
Id() uint
// Return tuner name
Name() string
}
// DVBService represents a service that can be received
type DVBService interface {
Id() uint16
}
////////////////////////////////////////////////////////////////////////////////
// CONSTANTS
const (
MEDIA_FLAG_ALBUM MediaFlag = (1 << iota) // Is part of an album
MEDIA_FLAG_ALBUM_TRACK // Is an album track
MEDIA_FLAG_ALBUM_COMPILATION // Album is a compliation
MEDIA_FLAG_TVSHOW // Is part of a TV Show
MEDIA_FLAG_TVSHOW_EPISODE // Is a TV Show episode
MEDIA_FLAG_FILE // Is a file
MEDIA_FLAG_VIDEO // Contains video
MEDIA_FLAG_AUDIO // Contains audio
MEDIA_FLAG_SUBTITLE // Contains subtitles
MEDIA_FLAG_DATA // Contains data stream
MEDIA_FLAG_ATTACHMENT // Contains attachment
MEDIA_FLAG_ARTWORK // Contains artwork
MEDIA_FLAG_CAPTIONS // Contains captions
MEDIA_FLAG_ENCODER // Is an encoder
MEDIA_FLAG_DECODER // Is an decoder
MEDIA_FLAG_NONE MediaFlag = 0
MEDIA_FLAG_MIN = MEDIA_FLAG_ALBUM
MEDIA_FLAG_MAX = MEDIA_FLAG_DECODER
)
const (
MEDIA_KEY_BRAND_MAJOR MediaKey = "major_brand" // string
MEDIA_KEY_BRAND_COMPATIBLE MediaKey = "compatible_brands" // string
MEDIA_KEY_CREATED MediaKey = "creation_time" // time.Time
MEDIA_KEY_ENCODER MediaKey = "encoder" // string
MEDIA_KEY_ALBUM MediaKey = "album" // string
MEDIA_KEY_ALBUM_ARTIST MediaKey = "artist" // string
MEDIA_KEY_COMMENT MediaKey = "comment" // string
MEDIA_KEY_COMPOSER MediaKey = "composer" // string
MEDIA_KEY_COPYRIGHT MediaKey = "copyright" // string
MEDIA_KEY_YEAR MediaKey = "date" // uint
MEDIA_KEY_DISC MediaKey = "disc" // uint
MEDIA_KEY_ENCODED_BY MediaKey = "encoded_by" // string
MEDIA_KEY_FILENAME MediaKey = "filename" // string
MEDIA_KEY_GENRE MediaKey = "genre" // string
MEDIA_KEY_LANGUAGE MediaKey = "language" // string
MEDIA_KEY_PERFORMER MediaKey = "performer" // string
MEDIA_KEY_PUBLISHER MediaKey = "publisher" // string
MEDIA_KEY_SERVICE_NAME MediaKey = "service_name" // string
MEDIA_KEY_SERVICE_PROVIDER MediaKey = "service_provider" // string
MEDIA_KEY_TITLE MediaKey = "title" // string
MEDIA_KEY_TRACK MediaKey = "track" // uint
MEDIA_KEY_VERSION_MAJOR MediaKey = "major_version" // string
MEDIA_KEY_VERSION_MINOR MediaKey = "minor_version" // string
MEDIA_KEY_SHOW MediaKey = "show" // string
MEDIA_KEY_SEASON MediaKey = "season_number" // uint
MEDIA_KEY_EPISODE_SORT MediaKey = "episode_sort" // string
MEDIA_KEY_EPISODE_ID MediaKey = "episode_id" // uint
MEDIA_KEY_COMPILATION MediaKey = "compilation" // bool
MEDIA_KEY_GAPLESS_PLAYBACK MediaKey = "gapless_playback" // bool
MEDIA_KEY_ACCOUNT_ID MediaKey = "account_id" // string
MEDIA_KEY_DESCRIPTION MediaKey = "description" // string
MEDIA_KEY_MEDIA_TYPE MediaKey = "media_type" // string
MEDIA_KEY_PURCHASED MediaKey = "purchase_date" // time.Time
MEDIA_KEY_ALBUM_SORT MediaKey = "sort_album" // string
MEDIA_KEY_ARTIST_SORT MediaKey = "sort_artist" // string
MEDIA_KEY_TITLE_SORT MediaKey = "sort_name" // string
MEDIA_KEY_SYNOPSIS MediaKey = "synopsis" // string
MEDIA_KEY_GROUPING MediaKey = "grouping" // string
)
////////////////////////////////////////////////////////////////////////////////
// STRINGIFY
func (f MediaFlag) String() string {
if f == MEDIA_FLAG_NONE {
return f.FlagString()
}
str := ""
for v := MEDIA_FLAG_MIN; v <= MEDIA_FLAG_MAX; v <<= 1 {
if f&v == v {
str += v.FlagString() + "|"
}
}
return strings.TrimSuffix(str, "|")
}
func (f MediaFlag) FlagString() string {
switch f {
case MEDIA_FLAG_NONE:
return "MEDIA_FLAG_NONE"
case MEDIA_FLAG_ALBUM:
return "MEDIA_FLAG_ALBUM"
case MEDIA_FLAG_ALBUM_TRACK:
return "MEDIA_FLAG_ALBUM_TRACK"
case MEDIA_FLAG_ALBUM_COMPILATION:
return "MEDIA_FLAG_ALBUM_COMPILATION"
case MEDIA_FLAG_TVSHOW:
return "MEDIA_FLAG_TVSHOW"
case MEDIA_FLAG_TVSHOW_EPISODE:
return "MEDIA_FLAG_TVSHOW_EPISODE"
case MEDIA_FLAG_FILE:
return "MEDIA_FLAG_FILE"
case MEDIA_FLAG_VIDEO:
return "MEDIA_FLAG_VIDEO"
case MEDIA_FLAG_AUDIO:
return "MEDIA_FLAG_AUDIO"
case MEDIA_FLAG_SUBTITLE:
return "MEDIA_FLAG_SUBTITLE"
case MEDIA_FLAG_DATA:
return "MEDIA_FLAG_DATA"
case MEDIA_FLAG_ATTACHMENT:
return "MEDIA_FLAG_ATTACHMENT"
case MEDIA_FLAG_ARTWORK:
return "MEDIA_FLAG_ARTWORK"
case MEDIA_FLAG_CAPTIONS:
return "MEDIA_FLAG_CAPTIONS"
case MEDIA_FLAG_ENCODER:
return "MEDIA_FLAG_ENCODER"
case MEDIA_FLAG_DECODER:
return "MEDIA_FLAG_DECODER"
default:
return "[?? Invalid MediaFlag]"
}
}