forked from dhowden/tag
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathogg.go
120 lines (101 loc) · 2.48 KB
/
ogg.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
// Copyright 2015, David Howden
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package tag
import (
"errors"
"io"
"os"
)
const (
idType int = 1
commentType = 3
)
// ReadOGGTags reads OGG metadata from the io.ReadSeeker, returning the resulting
// metadata in a Metadata implementation, or non-nil error if there was a problem.
// See http://www.xiph.org/vorbis/doc/Vorbis_I_spec.html
// and http://www.xiph.org/ogg/doc/framing.html for details.
func ReadOGGTags(r io.ReadSeeker) (Metadata, error) {
oggs, err := readString(r, 4)
if err != nil {
return nil, err
}
if oggs != "OggS" {
return nil, errors.New("expected 'OggS'")
}
// Skip 22 bytes of Page header to read page_segments length byte at position 26
// See http://www.xiph.org/ogg/doc/framing.html
_, err = r.Seek(22, os.SEEK_CUR)
if err != nil {
return nil, err
}
nS, err := readInt(r, 1)
if err != nil {
return nil, err
}
// Seek and discard the segments
_, err = r.Seek(int64(nS), os.SEEK_CUR)
if err != nil {
return nil, err
}
// First packet type is identification, type 1
t, err := readInt(r, 1)
if err != nil {
return nil, err
}
if t != idType {
return nil, errors.New("expected 'vorbis' identification type 1")
}
// Seek and discard 29 bytes from common and identification header
// See http://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-610004.2
_, err = r.Seek(29, os.SEEK_CUR)
if err != nil {
return nil, err
}
// Beginning of a new page. Comment packet is on a separate page
// See http://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-132000A.2
oggs, err = readString(r, 4)
if err != nil {
return nil, err
}
if oggs != "OggS" {
return nil, errors.New("expected 'OggS'")
}
// Skip page 2 header, same as line 30
_, err = r.Seek(22, os.SEEK_CUR)
if err != nil {
return nil, err
}
nS, err = readInt(r, 1)
if err != nil {
return nil, err
}
_, err = r.Seek(int64(nS), os.SEEK_CUR)
if err != nil {
return nil, err
}
// Packet type is comment, type 3
t, err = readInt(r, 1)
if err != nil {
return nil, err
}
if t != commentType {
return nil, errors.New("expected 'vorbis' comment type 3")
}
// Seek and discard 6 bytes from common header
_, err = r.Seek(6, os.SEEK_CUR)
if err != nil {
return nil, err
}
m := &metadataOGG{
newMetadataVorbis(),
}
err = m.readVorbisComment(r)
return m, err
}
type metadataOGG struct {
*metadataVorbis
}
func (m *metadataOGG) FileType() FileType {
return OGG
}