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
6b3187cc
authored
Jan 15, 2022
by
Marcel Dopita
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Support MKV embedded WebVTT captions
parent
b3981be8
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
45 additions
and
2 deletions
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mkv/MatroskaExtractor.java
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mkv/MatroskaExtractor.java
View file @
6b3187cc
...
@@ -138,6 +138,7 @@ public class MatroskaExtractor implements Extractor {
...
@@ -138,6 +138,7 @@ public class MatroskaExtractor implements Extractor {
private
static
final
String
CODEC_ID_PCM_FLOAT
=
"A_PCM/FLOAT/IEEE"
;
private
static
final
String
CODEC_ID_PCM_FLOAT
=
"A_PCM/FLOAT/IEEE"
;
private
static
final
String
CODEC_ID_SUBRIP
=
"S_TEXT/UTF8"
;
private
static
final
String
CODEC_ID_SUBRIP
=
"S_TEXT/UTF8"
;
private
static
final
String
CODEC_ID_ASS
=
"S_TEXT/ASS"
;
private
static
final
String
CODEC_ID_ASS
=
"S_TEXT/ASS"
;
private
static
final
String
CODEC_ID_VTT
=
"S_TEXT/WEBVTT"
;
private
static
final
String
CODEC_ID_VOBSUB
=
"S_VOBSUB"
;
private
static
final
String
CODEC_ID_VOBSUB
=
"S_VOBSUB"
;
private
static
final
String
CODEC_ID_PGS
=
"S_HDMV/PGS"
;
private
static
final
String
CODEC_ID_PGS
=
"S_HDMV/PGS"
;
private
static
final
String
CODEC_ID_DVBSUB
=
"S_DVBSUB"
;
private
static
final
String
CODEC_ID_DVBSUB
=
"S_DVBSUB"
;
...
@@ -323,6 +324,32 @@ public class MatroskaExtractor implements Extractor {
...
@@ -323,6 +324,32 @@ public class MatroskaExtractor implements Extractor {
/** The format of an SSA timecode. */
/** The format of an SSA timecode. */
private
static
final
String
SSA_TIMECODE_FORMAT
=
"%01d:%02d:%02d:%02d"
;
private
static
final
String
SSA_TIMECODE_FORMAT
=
"%01d:%02d:%02d:%02d"
;
/**
* A template for the prefix that must be added to each VTT sample.
*
* <p>The display time of each subtitle is passed as {@code timeUs} to {@link
* TrackOutput#sampleMetadata}. The start and end timecodes in this template are relative to
* {@code timeUs}. Hence the start timecode is always zero. The 12 byte end timecode starting at
* {@link #VTT_PREFIX_END_TIMECODE_OFFSET} is set to a placeholder value, and must be replaced
* with the duration of the subtitle.
*
* <p>Equivalent to the UTF-8 string: "WEBVTT\n\n00:00:00.000 --> 00:00:00.000\n".
*/
private
static
final
byte
[]
VTT_PREFIX
=
new
byte
[]{
87
,
69
,
66
,
86
,
84
,
84
,
10
,
10
,
48
,
48
,
58
,
48
,
48
,
58
,
48
,
48
,
46
,
48
,
48
,
48
,
32
,
45
,
45
,
62
,
32
,
48
,
48
,
58
,
48
,
48
,
58
,
48
,
48
,
46
,
48
,
48
,
48
,
10
};
/** The byte offset of the end timecode in {@link #VTT_PREFIX}. */
private
static
final
int
VTT_PREFIX_END_TIMECODE_OFFSET
=
25
;
/**
* The value by which to divide a time in microseconds to convert it to the unit of the last value
* in a VTT timecode (milliseconds).
*/
private
static
final
long
VTT_TIMECODE_LAST_VALUE_SCALING_FACTOR
=
1000
;
/** The format of a VTT timecode. */
private
static
final
String
VTT_TIMECODE_FORMAT
=
"%02d:%02d:%02d.%03d"
;
/** The length in bytes of a WAVEFORMATEX structure. */
/** The length in bytes of a WAVEFORMATEX structure. */
private
static
final
int
WAVE_FORMAT_SIZE
=
18
;
private
static
final
int
WAVE_FORMAT_SIZE
=
18
;
/** Format tag indicating a WAVEFORMATEXTENSIBLE structure. */
/** Format tag indicating a WAVEFORMATEXTENSIBLE structure. */
...
@@ -1342,7 +1369,8 @@ public class MatroskaExtractor implements Extractor {
...
@@ -1342,7 +1369,8 @@ public class MatroskaExtractor implements Extractor {
track
.
trueHdSampleRechunker
.
sampleMetadata
(
track
.
trueHdSampleRechunker
.
sampleMetadata
(
track
.
output
,
timeUs
,
flags
,
size
,
offset
,
track
.
cryptoData
);
track
.
output
,
timeUs
,
flags
,
size
,
offset
,
track
.
cryptoData
);
}
else
{
}
else
{
if
(
CODEC_ID_SUBRIP
.
equals
(
track
.
codecId
)
||
CODEC_ID_ASS
.
equals
(
track
.
codecId
))
{
if
(
CODEC_ID_SUBRIP
.
equals
(
track
.
codecId
)
||
CODEC_ID_ASS
.
equals
(
track
.
codecId
)
||
CODEC_ID_VTT
.
equals
(
track
.
codecId
))
{
if
(
blockSampleCount
>
1
)
{
if
(
blockSampleCount
>
1
)
{
Log
.
w
(
TAG
,
"Skipping subtitle sample in laced block."
);
Log
.
w
(
TAG
,
"Skipping subtitle sample in laced block."
);
}
else
if
(
blockDurationUs
==
C
.
TIME_UNSET
)
{
}
else
if
(
blockDurationUs
==
C
.
TIME_UNSET
)
{
...
@@ -1415,6 +1443,9 @@ public class MatroskaExtractor implements Extractor {
...
@@ -1415,6 +1443,9 @@ public class MatroskaExtractor implements Extractor {
}
else
if
(
CODEC_ID_ASS
.
equals
(
track
.
codecId
))
{
}
else
if
(
CODEC_ID_ASS
.
equals
(
track
.
codecId
))
{
writeSubtitleSampleData
(
input
,
SSA_PREFIX
,
size
);
writeSubtitleSampleData
(
input
,
SSA_PREFIX
,
size
);
return
finishWriteSampleData
();
return
finishWriteSampleData
();
}
else
if
(
CODEC_ID_VTT
.
equals
(
track
.
codecId
))
{
writeSubtitleSampleData
(
input
,
VTT_PREFIX
,
size
);
return
finishWriteSampleData
();
}
}
TrackOutput
output
=
track
.
output
;
TrackOutput
output
=
track
.
output
;
...
@@ -1641,7 +1672,8 @@ public class MatroskaExtractor implements Extractor {
...
@@ -1641,7 +1672,8 @@ public class MatroskaExtractor implements Extractor {
* <p>See documentation on {@link #SSA_DIALOGUE_FORMAT} and {@link #SUBRIP_PREFIX} for why we use
* <p>See documentation on {@link #SSA_DIALOGUE_FORMAT} and {@link #SUBRIP_PREFIX} for why we use
* the duration as the end timecode.
* the duration as the end timecode.
*
*
* @param codecId The subtitle codec; must be {@link #CODEC_ID_SUBRIP} or {@link #CODEC_ID_ASS}.
* @param codecId The subtitle codec; must be {@link #CODEC_ID_SUBRIP}, {@link #CODEC_ID_ASS} or
* {@link #CODEC_ID_VTT}.
* @param durationUs The duration of the sample, in microseconds.
* @param durationUs The duration of the sample, in microseconds.
* @param subtitleData The subtitle sample in which to overwrite the end timecode (output
* @param subtitleData The subtitle sample in which to overwrite the end timecode (output
* parameter).
* parameter).
...
@@ -1662,6 +1694,12 @@ public class MatroskaExtractor implements Extractor {
...
@@ -1662,6 +1694,12 @@ public class MatroskaExtractor implements Extractor {
durationUs
,
SSA_TIMECODE_FORMAT
,
SSA_TIMECODE_LAST_VALUE_SCALING_FACTOR
);
durationUs
,
SSA_TIMECODE_FORMAT
,
SSA_TIMECODE_LAST_VALUE_SCALING_FACTOR
);
endTimecodeOffset
=
SSA_PREFIX_END_TIMECODE_OFFSET
;
endTimecodeOffset
=
SSA_PREFIX_END_TIMECODE_OFFSET
;
break
;
break
;
case
CODEC_ID_VTT:
endTimecode
=
formatSubtitleTimecode
(
durationUs
,
VTT_TIMECODE_FORMAT
,
VTT_TIMECODE_LAST_VALUE_SCALING_FACTOR
);
endTimecodeOffset
=
VTT_PREFIX_END_TIMECODE_OFFSET
;
break
;
default
:
default
:
throw
new
IllegalArgumentException
();
throw
new
IllegalArgumentException
();
}
}
...
@@ -1830,6 +1868,7 @@ public class MatroskaExtractor implements Extractor {
...
@@ -1830,6 +1868,7 @@ public class MatroskaExtractor implements Extractor {
case
CODEC_ID_PCM_FLOAT:
case
CODEC_ID_PCM_FLOAT:
case
CODEC_ID_SUBRIP:
case
CODEC_ID_SUBRIP:
case
CODEC_ID_ASS:
case
CODEC_ID_ASS:
case
CODEC_ID_VTT:
case
CODEC_ID_VOBSUB:
case
CODEC_ID_VOBSUB:
case
CODEC_ID_PGS:
case
CODEC_ID_PGS:
case
CODEC_ID_DVBSUB:
case
CODEC_ID_DVBSUB:
...
@@ -2157,6 +2196,9 @@ public class MatroskaExtractor implements Extractor {
...
@@ -2157,6 +2196,9 @@ public class MatroskaExtractor implements Extractor {
mimeType
=
MimeTypes
.
TEXT_SSA
;
mimeType
=
MimeTypes
.
TEXT_SSA
;
initializationData
=
ImmutableList
.
of
(
SSA_DIALOGUE_FORMAT
,
getCodecPrivate
(
codecId
));
initializationData
=
ImmutableList
.
of
(
SSA_DIALOGUE_FORMAT
,
getCodecPrivate
(
codecId
));
break
;
break
;
case
CODEC_ID_VTT:
mimeType
=
MimeTypes
.
TEXT_VTT
;
break
;
case
CODEC_ID_VOBSUB:
case
CODEC_ID_VOBSUB:
mimeType
=
MimeTypes
.
APPLICATION_VOBSUB
;
mimeType
=
MimeTypes
.
APPLICATION_VOBSUB
;
initializationData
=
ImmutableList
.
of
(
getCodecPrivate
(
codecId
));
initializationData
=
ImmutableList
.
of
(
getCodecPrivate
(
codecId
));
...
@@ -2245,6 +2287,7 @@ public class MatroskaExtractor implements Extractor {
...
@@ -2245,6 +2287,7 @@ public class MatroskaExtractor implements Extractor {
.
setColorInfo
(
colorInfo
);
.
setColorInfo
(
colorInfo
);
}
else
if
(
MimeTypes
.
APPLICATION_SUBRIP
.
equals
(
mimeType
)
}
else
if
(
MimeTypes
.
APPLICATION_SUBRIP
.
equals
(
mimeType
)
||
MimeTypes
.
TEXT_SSA
.
equals
(
mimeType
)
||
MimeTypes
.
TEXT_SSA
.
equals
(
mimeType
)
||
MimeTypes
.
TEXT_VTT
.
equals
(
mimeType
)
||
MimeTypes
.
APPLICATION_VOBSUB
.
equals
(
mimeType
)
||
MimeTypes
.
APPLICATION_VOBSUB
.
equals
(
mimeType
)
||
MimeTypes
.
APPLICATION_PGS
.
equals
(
mimeType
)
||
MimeTypes
.
APPLICATION_PGS
.
equals
(
mimeType
)
||
MimeTypes
.
APPLICATION_DVBSUBS
.
equals
(
mimeType
))
{
||
MimeTypes
.
APPLICATION_DVBSUBS
.
equals
(
mimeType
))
{
...
...
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