Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
SDK
/
exoplayer
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
2bb2e2c4
authored
Mar 03, 2015
by
Andrey Udovenko
Browse files
Options
_('Browse Files')
Download
Plain Diff
Merge pull request #324 from jeoliva/id3
Add support for GEOB and PRIV ID3 frames.
parents
ea95db23
b03c8a71
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
141 additions
and
11 deletions
demo/src/main/java/com/google/android/exoplayer/demo/Samples.java
library/src/main/java/com/google/android/exoplayer/metadata/GeobMetadata.java
library/src/main/java/com/google/android/exoplayer/metadata/Id3Parser.java
library/src/main/java/com/google/android/exoplayer/metadata/PrivMetadata.java
demo/src/main/java/com/google/android/exoplayer/demo/Samples.java
View file @
2bb2e2c4
...
...
@@ -123,6 +123,9 @@ import java.util.Locale;
new
Sample
(
"Apple AAC media playlist"
,
"https://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/gear0/"
+
"prog_index.m3u8"
,
DemoUtil
.
TYPE_HLS
),
new
Sample
(
"Apple ID3 metadata"
,
"http://devimages.apple.com/samplecode/adDemo/"
+
"ad.m3u8"
,
DemoUtil
.
TYPE_HLS
),
};
public
static
final
Sample
[]
MISC
=
new
Sample
[]
{
...
...
library/src/main/java/com/google/android/exoplayer/metadata/GeobMetadata.java
0 → 100644
View file @
2bb2e2c4
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com
.
google
.
android
.
exoplayer
.
metadata
;
/**
* A metadata that contains parsed ID3 GEOB (General Encapsulated Object) frame data associated
* with time indices.
*/
public
class
GeobMetadata
{
public
static
final
String
TYPE
=
"GEOB"
;
public
final
String
mimeType
;
public
final
String
filename
;
public
final
String
description
;
public
final
byte
[]
data
;
public
GeobMetadata
(
String
mimeType
,
String
filename
,
String
description
,
byte
[]
data
)
{
this
.
mimeType
=
mimeType
;
this
.
filename
=
filename
;
this
.
description
=
description
;
this
.
data
=
data
;
}
}
library/src/main/java/com/google/android/exoplayer/metadata/Id3Parser.java
View file @
2bb2e2c4
...
...
@@ -29,6 +29,11 @@ import java.util.Map;
*/
public
class
Id3Parser
implements
MetadataParser
<
Map
<
String
,
Object
>>
{
private
static
final
int
ID3_TEXT_ENCODING_ISO_8859_1
=
0
;
private
static
final
int
ID3_TEXT_ENCODING_UTF_16
=
1
;
private
static
final
int
ID3_TEXT_ENCODING_UTF_16BE
=
2
;
private
static
final
int
ID3_TEXT_ENCODING_UTF_8
=
3
;
@Override
public
boolean
canParse
(
String
mimeType
)
{
return
mimeType
.
equals
(
MimeTypes
.
APPLICATION_ID3
);
...
...
@@ -60,13 +65,48 @@ public class Id3Parser implements MetadataParser<Map<String, Object>> {
byte
[]
frame
=
new
byte
[
frameSize
-
1
];
id3Data
.
readBytes
(
frame
,
0
,
frameSize
-
1
);
int
firstZeroIndex
=
indexOf
(
frame
,
0
,
(
byte
)
0
);
int
firstZeroIndex
=
indexOf
EOS
(
frame
,
0
,
encoding
);
String
description
=
new
String
(
frame
,
0
,
firstZeroIndex
,
charset
);
int
valueStartIndex
=
indexOfNot
(
frame
,
firstZeroIndex
,
(
byte
)
0
);
int
valueEndIndex
=
indexOf
(
frame
,
valueStartIndex
,
(
byte
)
0
);
int
valueStartIndex
=
firstZeroIndex
+
delimiterLength
(
encoding
);
int
valueEndIndex
=
indexOf
EOS
(
frame
,
valueStartIndex
,
encoding
);
String
value
=
new
String
(
frame
,
valueStartIndex
,
valueEndIndex
-
valueStartIndex
,
charset
);
metadata
.
put
(
TxxxMetadata
.
TYPE
,
new
TxxxMetadata
(
description
,
value
));
}
else
if
(
frameId0
==
'P'
&&
frameId1
==
'R'
&&
frameId2
==
'I'
&&
frameId3
==
'V'
)
{
// Check frame ID == PRIV
byte
[]
frame
=
new
byte
[
frameSize
];
id3Data
.
readBytes
(
frame
,
0
,
frameSize
);
int
firstZeroIndex
=
indexOf
(
frame
,
0
,
(
byte
)
0
);
String
owner
=
new
String
(
frame
,
0
,
firstZeroIndex
,
"ISO-8859-1"
);
byte
[]
privateData
=
new
byte
[
frameSize
-
firstZeroIndex
-
1
];
System
.
arraycopy
(
frame
,
firstZeroIndex
+
1
,
privateData
,
0
,
frameSize
-
firstZeroIndex
-
1
);
metadata
.
put
(
PrivMetadata
.
TYPE
,
new
PrivMetadata
(
owner
,
privateData
));
}
else
if
(
frameId0
==
'G'
&&
frameId1
==
'E'
&&
frameId2
==
'O'
&&
frameId3
==
'B'
)
{
// Check frame ID == GEOB
int
encoding
=
id3Data
.
readUnsignedByte
();
String
charset
=
getCharsetName
(
encoding
);
byte
[]
frame
=
new
byte
[
frameSize
-
1
];
id3Data
.
readBytes
(
frame
,
0
,
frameSize
-
1
);
int
firstZeroIndex
=
indexOf
(
frame
,
0
,
(
byte
)
0
);
String
mimeType
=
new
String
(
frame
,
0
,
firstZeroIndex
,
"ISO-8859-1"
);
int
filenameStartIndex
=
firstZeroIndex
+
1
;
int
filenameEndIndex
=
indexOfEOS
(
frame
,
filenameStartIndex
,
encoding
);
String
filename
=
new
String
(
frame
,
filenameStartIndex
,
filenameEndIndex
-
filenameStartIndex
,
charset
);
int
descriptionStartIndex
=
filenameEndIndex
+
delimiterLength
(
encoding
);
int
descriptionEndIndex
=
indexOfEOS
(
frame
,
descriptionStartIndex
,
encoding
);
String
description
=
new
String
(
frame
,
descriptionStartIndex
,
descriptionEndIndex
-
descriptionStartIndex
,
charset
);
int
objectDataSize
=
frameSize
-
1
/* encoding byte */
-
descriptionEndIndex
-
delimiterLength
(
encoding
);
byte
[]
objectData
=
new
byte
[
objectDataSize
];
System
.
arraycopy
(
frame
,
descriptionEndIndex
+
delimiterLength
(
encoding
),
objectData
,
0
,
objectDataSize
);
metadata
.
put
(
GeobMetadata
.
TYPE
,
new
GeobMetadata
(
mimeType
,
filename
,
description
,
objectData
));
}
else
{
String
type
=
String
.
format
(
"%c%c%c%c"
,
frameId0
,
frameId1
,
frameId2
,
frameId3
);
byte
[]
frame
=
new
byte
[
frameSize
];
...
...
@@ -89,15 +129,30 @@ public class Id3Parser implements MetadataParser<Map<String, Object>> {
return
data
.
length
;
}
private
static
int
indexOfNot
(
byte
[]
data
,
int
fromIndex
,
byte
key
)
{
for
(
int
i
=
fromIndex
;
i
<
data
.
length
;
i
++)
{
if
(
data
[
i
]
!=
key
)
{
return
i
;
private
static
int
indexOfEOS
(
byte
[]
data
,
int
fromIndex
,
int
encodingByte
)
{
int
terminationPos
=
indexOf
(
data
,
fromIndex
,
(
byte
)
0
);
// For single byte encoding charsets, we are done
if
(
encodingByte
==
ID3_TEXT_ENCODING_ISO_8859_1
||
encodingByte
==
ID3_TEXT_ENCODING_UTF_8
)
{
return
terminationPos
;
}
// Otherwise, look for a two zero bytes
while
(
terminationPos
<
data
.
length
-
1
)
{
if
(
data
[
terminationPos
+
1
]
==
(
byte
)
0
)
{
return
terminationPos
;
}
terminationPos
=
indexOf
(
data
,
terminationPos
+
1
,
(
byte
)
0
);
}
return
data
.
length
;
}
private
static
int
delimiterLength
(
int
encodingByte
)
{
return
(
encodingByte
==
ID3_TEXT_ENCODING_ISO_8859_1
||
encodingByte
==
ID3_TEXT_ENCODING_UTF_8
)
?
1
:
2
;
}
/**
* Parses an ID3 header.
*
...
...
@@ -142,13 +197,13 @@ public class Id3Parser implements MetadataParser<Map<String, Object>> {
*/
private
static
String
getCharsetName
(
int
encodingByte
)
{
switch
(
encodingByte
)
{
case
0
:
case
ID3_TEXT_ENCODING_ISO_8859_1
:
return
"ISO-8859-1"
;
case
1
:
case
ID3_TEXT_ENCODING_UTF_16
:
return
"UTF-16"
;
case
2
:
case
ID3_TEXT_ENCODING_UTF_16BE
:
return
"UTF-16BE"
;
case
3
:
case
ID3_TEXT_ENCODING_UTF_8
:
return
"UTF-8"
;
default
:
return
"ISO-8859-1"
;
...
...
library/src/main/java/com/google/android/exoplayer/metadata/PrivMetadata.java
0 → 100644
View file @
2bb2e2c4
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com
.
google
.
android
.
exoplayer
.
metadata
;
/**
* A metadata that contains parsed ID3 PRIV (Private) frame data associated
* with time indices.
*/
public
class
PrivMetadata
{
public
static
final
String
TYPE
=
"PRIV"
;
public
final
String
owner
;
public
final
byte
[]
privateData
;
public
PrivMetadata
(
String
owner
,
byte
[]
privateData
)
{
this
.
owner
=
owner
;
this
.
privateData
=
privateData
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment