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
e4e02f91
authored
Sep 28, 2015
by
Oliver Woodman
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Further improve WebVTT parser according to WebVTT spec
parent
71f542f7
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
171 additions
and
48 deletions
library/src/androidTest/assets/webvtt/live_typical
library/src/androidTest/assets/webvtt/typical_with_comments
library/src/androidTest/assets/webvtt/typical_with_metadata → library/src/androidTest/assets/webvtt/with_positioning
library/src/androidTest/assets/webvtt/typical_with_tags → library/src/androidTest/assets/webvtt/with_tags
library/src/androidTest/java/com/google/android/exoplayer/text/webvtt/WebvttParserTest.java
library/src/main/java/com/google/android/exoplayer/text/Cue.java
library/src/main/java/com/google/android/exoplayer/text/CuePainter.java
library/src/main/java/com/google/android/exoplayer/text/SubtitleLayout.java
library/src/main/java/com/google/android/exoplayer/text/webvtt/WebvttCue.java
library/src/main/java/com/google/android/exoplayer/text/webvtt/WebvttParser.java
library/src/androidTest/assets/webvtt/live_typical
deleted
100644 → 0
View file @
71f542f7
WEBVTT
00:00.000 --> 00:01.234
This is the first subtitle.
00:02.345 --> 00:03.456
This is the second subtitle.
library/src/androidTest/assets/webvtt/typical_with_comments
View file @
e4e02f91
...
...
@@ -8,7 +8,9 @@ with multiple lines
00:00.000 --> 00:01.234
This is the first subtitle.
NOTE Single line comment
NOTE Single line comment with a space
NOTE Single line comment with a tab
2
00:02.345 --> 00:03.456
...
...
library/src/androidTest/assets/webvtt/
typical_with_metadata
→
library/src/androidTest/assets/webvtt/
with_positioning
View file @
e4e02f91
...
...
@@ -16,7 +16,13 @@ NOTE Line as percentage and line alignment
00:04.000 --> 00:05.000 line:45%,end align:middle size:35%
This is the third subtitle.
NOTE Line as absolute negative number and without line alignment
NOTE Line as absolute negative number and without line alignment.
00:06.000 --> 00:07.000 line:-10 align:middle
This is the fourth subtitle.
NOTE The positioning alignment should be inherited from align.
00:07.000 --> 00:08.000 position:10% align:end size:10%
This is the fifth subtitle.
00:06.000 --> 00:07.000 line:-10 align:middle size:35%
This is the forth subtitle.
library/src/androidTest/assets/webvtt/
typical_
with_tags
→
library/src/androidTest/assets/webvtt/with_tags
View file @
e4e02f91
File moved
library/src/androidTest/java/com/google/android/exoplayer/text/webvtt/WebvttParserTest.java
View file @
e4e02f91
This diff is collapsed.
Click to expand it.
library/src/main/java/com/google/android/exoplayer/text/Cue.java
View file @
e4e02f91
...
...
@@ -23,30 +23,117 @@ import android.text.Layout.Alignment;
public
class
Cue
{
/**
*
Used by some methods to indicate that no value is set
.
*
An unset position or width
.
*/
public
static
final
int
UNSET_VALUE
=
-
1
;
public
static
final
float
DIMEN_UNSET
=
Float
.
MIN_VALUE
;
/**
* An unset anchor or line type value.
*/
public
static
final
int
TYPE_UNSET
=
Integer
.
MIN_VALUE
;
/**
* Anchors the left (for horizontal positions) or top (for vertical positions) edge of the cue
* box.
*/
public
static
final
int
ANCHOR_TYPE_START
=
0
;
/**
* Anchors the middle of the cue box.
*/
public
static
final
int
ANCHOR_TYPE_MIDDLE
=
1
;
/**
* Anchors the right (for horizontal positions) or bottom (for vertical positions) edge of the cue
* box.
*/
public
static
final
int
ANCHOR_TYPE_END
=
2
;
/**
* Value for {@link #lineType} when {@link #line} is a fractional position.
*/
public
static
final
int
LINE_TYPE_FRACTION
=
0
;
/**
* Value for {@link #lineType} when {@link #line} is a line number.
*/
public
static
final
int
LINE_TYPE_NUMBER
=
1
;
/**
* The cue text. Note the {@link CharSequence} may be decorated with styling spans.
*/
public
final
CharSequence
text
;
public
final
int
line
;
public
final
int
position
;
public
final
Alignment
alignment
;
public
final
int
size
;
/**
* The alignment of the cue text within the cue box.
*/
public
final
Alignment
textAlignment
;
/**
* The position of the {@link #lineAnchor} of the cue box within the viewport in the direction
* orthogonal to the writing direction, or {@link #DIMEN_UNSET}. When set, the interpretation of
* the value depends on the value of {@link #lineType}.
* <p>
* For horizontal text and {@link #lineType} equal to {@link #LINE_TYPE_FRACTION}, this is the
* fractional vertical position relative to the top of the viewport.
*/
public
final
float
line
;
/**
* The type of the {@link #line} value.
* <p>
* {@link #LINE_TYPE_FRACTION} indicates that {@link #line} is a fractional position within the
* viewport.
* <p>
* {@link #LINE_TYPE_NUMBER} indicates that {@link #line} is a line number, where the size of each
* line is taken to be the size of the first line of the cue. When {@link #line} is greater than
* or equal to 0, lines count from the start of the viewport (the first line is numbered 0). When
* {@link #line} is negative, lines count from the end of the viewport (the last line is numbered
* -1). For horizontal text the size of the first line of the cue is its height, and the start
* and end of the viewport are the top and bottom respectively.
*/
public
final
int
lineType
;
/**
* The cue box anchor positioned by {@link #line}. One of {@link #ANCHOR_TYPE_START},
* {@link #ANCHOR_TYPE_MIDDLE}, {@link #ANCHOR_TYPE_END} and {@link #TYPE_UNSET}.
* <p>
* For the normal case of horizontal text, {@link #ANCHOR_TYPE_START}, {@link #ANCHOR_TYPE_MIDDLE}
* and {@link #ANCHOR_TYPE_END} correspond to the top, middle and bottom of the cue box
* respectively.
*/
public
final
int
lineAnchor
;
/**
* The fractional position of the {@link #positionAnchor} of the cue box within the viewport in
* the direction orthogonal to {@link #line}, or {@link #DIMEN_UNSET}.
* <p>
* For horizontal text, this is the horizontal position relative to the left of the viewport. Note
* that positioning is relative to the left of the viewport even in the case of right-to-left
* text.
*/
public
final
float
position
;
/**
* The cue box anchor positioned by {@link #position}. One of {@link #ANCHOR_TYPE_START},
* {@link #ANCHOR_TYPE_MIDDLE}, {@link #ANCHOR_TYPE_END} and {@link #TYPE_UNSET}.
* <p>
* For the normal case of horizontal text, {@link #ANCHOR_TYPE_START}, {@link #ANCHOR_TYPE_MIDDLE}
* and {@link #ANCHOR_TYPE_END} correspond to the left, middle and right of the cue box
* respectively.
*/
public
final
int
positionAnchor
;
/**
* The size of the cue box in the writing direction specified as a fraction of the viewport size
* in that direction, or {@link #DIMEN_UNSET}.
*/
public
final
float
size
;
public
Cue
()
{
this
(
null
);
}
public
Cue
(
CharSequence
text
)
{
this
(
text
,
UNSET_VALUE
,
UNSET_VALUE
,
null
,
UNSET_VALUE
);
this
(
text
,
null
,
DIMEN_UNSET
,
TYPE_UNSET
,
TYPE_UNSET
,
DIMEN_UNSET
,
TYPE_UNSET
,
DIMEN_UNSET
);
}
public
Cue
(
CharSequence
text
,
int
line
,
int
position
,
Alignment
alignment
,
int
size
)
{
public
Cue
(
CharSequence
text
,
Alignment
textAlignment
,
float
line
,
int
lineType
,
int
lineAnchor
,
float
position
,
int
positionAnchor
,
float
size
)
{
this
.
text
=
text
;
this
.
textAlignment
=
textAlignment
;
this
.
line
=
line
;
this
.
lineType
=
lineType
;
this
.
lineAnchor
=
lineAnchor
;
this
.
position
=
position
;
this
.
alignment
=
alignment
;
this
.
positionAnchor
=
positionAnchor
;
this
.
size
=
size
;
}
...
...
library/src/main/java/com/google/android/exoplayer/text/CuePainter.java
View file @
e4e02f91
...
...
@@ -63,8 +63,13 @@ import android.util.Log;
// Previous input variables.
private
CharSequence
cueText
;
private
int
cuePosition
;
private
Alignment
cueAlignment
;
private
Alignment
cueTextAlignment
;
private
float
cueLine
;
private
int
cueLineType
;
private
int
cueLineAnchor
;
private
float
cuePosition
;
private
int
cuePositionAnchor
;
private
float
cueSize
;
private
boolean
applyEmbeddedStyles
;
private
int
foregroundColor
;
private
int
backgroundColor
;
...
...
@@ -120,7 +125,7 @@ import android.util.Log;
* @param style The style to use when drawing the cue text.
* @param textSizePx The text size to use when drawing the cue text, in pixels.
* @param bottomPaddingFraction The bottom padding fraction to apply when {@link Cue#line} is
* {@link Cue#
UNSET_VALUE
}, as a fraction of the viewport height
* {@link Cue#
DIMEN_UNSET
}, as a fraction of the viewport height
* @param canvas The canvas into which to draw.
* @param cueBoxLeft The left position of the enclosing cue box.
* @param cueBoxTop The top position of the enclosing cue box.
...
...
@@ -140,8 +145,13 @@ import android.util.Log;
cueText
=
cueText
.
toString
();
}
if
(
areCharSequencesEqual
(
this
.
cueText
,
cueText
)
&&
Util
.
areEqual
(
this
.
cueTextAlignment
,
cue
.
textAlignment
)
&&
this
.
cueLine
==
cue
.
line
&&
this
.
cueLineType
==
cue
.
lineType
&&
Util
.
areEqual
(
this
.
cueLineAnchor
,
cue
.
lineAnchor
)
&&
this
.
cuePosition
==
cue
.
position
&&
Util
.
areEqual
(
this
.
cueAlignment
,
cue
.
alignment
)
&&
Util
.
areEqual
(
this
.
cuePositionAnchor
,
cue
.
positionAnchor
)
&&
this
.
cueSize
==
cue
.
size
&&
this
.
applyEmbeddedStyles
==
applyEmbeddedStyles
&&
this
.
foregroundColor
==
style
.
foregroundColor
&&
this
.
backgroundColor
==
style
.
backgroundColor
...
...
@@ -161,8 +171,13 @@ import android.util.Log;
}
this
.
cueText
=
cueText
;
this
.
cueTextAlignment
=
cue
.
textAlignment
;
this
.
cueLine
=
cue
.
line
;
this
.
cueLineType
=
cue
.
lineType
;
this
.
cueLineAnchor
=
cue
.
lineAnchor
;
this
.
cuePosition
=
cue
.
position
;
this
.
cueAlignment
=
cue
.
alignment
;
this
.
cuePositionAnchor
=
cue
.
positionAnchor
;
this
.
cueSize
=
cue
.
size
;
this
.
applyEmbeddedStyles
=
applyEmbeddedStyles
;
this
.
foregroundColor
=
style
.
foregroundColor
;
this
.
backgroundColor
=
style
.
backgroundColor
;
...
...
@@ -182,16 +197,19 @@ import android.util.Log;
textPaint
.
setTextSize
(
textSizePx
);
int
textPaddingX
=
(
int
)
(
textSizePx
*
INNER_PADDING_RATIO
+
0.5f
);
int
availableWidth
=
parentWidth
-
textPaddingX
*
2
;
if
(
cueSize
!=
Cue
.
DIMEN_UNSET
)
{
availableWidth
=
(
int
)
(
availableWidth
*
cueSize
);
}
if
(
availableWidth
<=
0
)
{
Log
.
w
(
TAG
,
"Skipped drawing subtitle cue (insufficient space)"
);
return
;
}
Alignment
layoutAlignment
=
cueAlignment
==
null
?
Alignment
.
ALIGN_CENTER
:
cue
Alignment
;
textLayout
=
new
StaticLayout
(
cueText
,
textPaint
,
availableWidth
,
layou
tAlignment
,
spacingMult
,
Alignment
textAlignment
=
cueTextAlignment
==
null
?
Alignment
.
ALIGN_CENTER
:
cueText
Alignment
;
textLayout
=
new
StaticLayout
(
cueText
,
textPaint
,
availableWidth
,
tex
tAlignment
,
spacingMult
,
spacingAdd
,
true
);
int
textHeight
=
textLayout
.
getHeight
();
int
textWidth
=
0
;
int
lineCount
=
textLayout
.
getLineCount
();
...
...
@@ -202,14 +220,13 @@ import android.util.Log;
int
textLeft
;
int
textRight
;
if
(
cue
.
position
!=
Cue
.
UNSET_VALUE
)
{
if
(
cue
.
alignment
==
Alignment
.
ALIGN_OPPOSITE
)
{
textRight
=
(
parentWidth
*
cue
.
position
)
/
100
+
parentLeft
;
textLeft
=
Math
.
max
(
textRight
-
textWidth
,
parentLeft
);
}
else
{
textLeft
=
(
parentWidth
*
cue
.
position
)
/
100
+
parentLeft
;
textRight
=
Math
.
min
(
textLeft
+
textWidth
,
parentRight
);
}
if
(
cuePosition
!=
Cue
.
DIMEN_UNSET
)
{
int
anchorPosition
=
Math
.
round
(
parentWidth
*
cuePosition
)
+
parentLeft
;
textLeft
=
cuePositionAnchor
==
Cue
.
ANCHOR_TYPE_END
?
anchorPosition
-
textWidth
:
cuePositionAnchor
==
Cue
.
ANCHOR_TYPE_MIDDLE
?
(
anchorPosition
*
2
-
textWidth
)
/
2
:
anchorPosition
;
textLeft
=
Math
.
max
(
textLeft
,
parentLeft
);
textRight
=
Math
.
min
(
textLeft
+
textWidth
,
parentRight
);
}
else
{
textLeft
=
(
parentWidth
-
textWidth
)
/
2
;
textRight
=
textLeft
+
textWidth
;
...
...
@@ -217,12 +234,29 @@ import android.util.Log;
int
textTop
;
int
textBottom
;
if
(
cue
.
line
!=
Cue
.
UNSET_VALUE
)
{
textTop
=
(
parentHeight
*
cue
.
line
)
/
100
+
parentTop
;
if
(
cueLine
!=
Cue
.
DIMEN_UNSET
)
{
int
anchorPosition
;
if
(
cueLineType
==
Cue
.
LINE_TYPE_FRACTION
)
{
anchorPosition
=
Math
.
round
(
parentHeight
*
cueLine
)
+
parentTop
;
}
else
{
// cueLineType == Cue.LINE_TYPE_NUMBER
int
firstLineHeight
=
textLayout
.
getLineBottom
(
0
)
-
textLayout
.
getLineTop
(
0
);
if
(
cueLine
>=
0
)
{
anchorPosition
=
Math
.
round
(
cueLine
*
firstLineHeight
)
+
parentTop
;
}
else
{
anchorPosition
=
Math
.
round
(
cueLine
*
firstLineHeight
)
+
parentBottom
;
}
}
textTop
=
cueLineAnchor
==
Cue
.
ANCHOR_TYPE_END
?
anchorPosition
-
textHeight
:
cueLineAnchor
==
Cue
.
ANCHOR_TYPE_MIDDLE
?
(
anchorPosition
*
2
-
textHeight
)
/
2
:
anchorPosition
;
textBottom
=
textTop
+
textHeight
;
if
(
textBottom
>
parentBottom
)
{
textTop
=
parentBottom
-
textHeight
;
textBottom
=
parentBottom
;
}
else
if
(
textTop
<
parentTop
)
{
textTop
=
parentTop
;
textBottom
=
parentTop
+
textHeight
;
}
}
else
{
textTop
=
parentBottom
-
textHeight
-
(
int
)
(
parentHeight
*
bottomPaddingFraction
);
...
...
@@ -232,7 +266,7 @@ import android.util.Log;
textWidth
=
textRight
-
textLeft
;
// Update the derived drawing variables.
this
.
textLayout
=
new
StaticLayout
(
cueText
,
textPaint
,
textWidth
,
layou
tAlignment
,
spacingMult
,
this
.
textLayout
=
new
StaticLayout
(
cueText
,
textPaint
,
textWidth
,
tex
tAlignment
,
spacingMult
,
spacingAdd
,
true
);
this
.
textLeft
=
textLeft
;
this
.
textTop
=
textTop
;
...
...
library/src/main/java/com/google/android/exoplayer/text/SubtitleLayout.java
View file @
e4e02f91
...
...
@@ -38,7 +38,7 @@ public final class SubtitleLayout extends View {
public
static
final
float
DEFAULT_TEXT_SIZE_FRACTION
=
0.0533f
;
/**
* The default bottom padding to apply when {@link Cue#line} is {@link Cue#
UNSET_VALUE
}, as a
* The default bottom padding to apply when {@link Cue#line} is {@link Cue#
DIMEN_UNSET
}, as a
* fraction of the viewport height.
*
* @see #setBottomPaddingFraction(float)
...
...
@@ -174,7 +174,7 @@ public final class SubtitleLayout extends View {
}
/**
* Sets the bottom padding fraction to apply when {@link Cue#line} is {@link Cue#
UNSET_VALUE
},
* Sets the bottom padding fraction to apply when {@link Cue#line} is {@link Cue#
DIMEN_UNSET
},
* as a fraction of the view's remaining height after its top and bottom padding have been
* subtracted.
* <p>
...
...
library/src/main/java/com/google/android/exoplayer/text/webvtt/WebvttCue.java
View file @
e4e02f91
...
...
@@ -28,16 +28,17 @@ import android.text.Layout.Alignment;
public
final
long
endTime
;
public
WebvttCue
(
CharSequence
text
)
{
this
(
Cue
.
UNSET_VALUE
,
Cue
.
UNSET_VALUE
,
text
);
this
(
0
,
0
,
text
);
}
public
WebvttCue
(
long
startTime
,
long
endTime
,
CharSequence
text
)
{
this
(
startTime
,
endTime
,
text
,
Cue
.
UNSET_VALUE
,
Cue
.
UNSET_VALUE
,
null
,
Cue
.
UNSET_VALUE
);
this
(
startTime
,
endTime
,
text
,
null
,
Cue
.
DIMEN_UNSET
,
Cue
.
TYPE_UNSET
,
Cue
.
TYPE_UNSET
,
Cue
.
DIMEN_UNSET
,
Cue
.
TYPE_UNSET
,
Cue
.
DIMEN_UNSET
);
}
public
WebvttCue
(
long
startTime
,
long
endTime
,
CharSequence
text
,
int
line
,
int
position
,
Alignment
alignment
,
int
size
)
{
super
(
text
,
line
,
position
,
alignment
,
size
);
public
WebvttCue
(
long
startTime
,
long
endTime
,
CharSequence
text
,
Alignment
textAlignment
,
float
line
,
int
lineType
,
int
lineAnchor
,
float
position
,
int
positionAnchor
,
float
width
)
{
super
(
text
,
textAlignment
,
line
,
lineType
,
lineAnchor
,
position
,
positionAnchor
,
width
);
this
.
startTime
=
startTime
;
this
.
endTime
=
endTime
;
}
...
...
@@ -49,7 +50,7 @@ import android.text.Layout.Alignment;
* @return True if this cue should be placed in the default position; false otherwise.
*/
public
boolean
isNormalCue
()
{
return
(
line
==
UNSET_VALUE
&&
position
==
UNSET_VALUE
);
return
(
line
==
DIMEN_UNSET
&&
position
==
DIMEN_UNSET
);
}
}
library/src/main/java/com/google/android/exoplayer/text/webvtt/WebvttParser.java
View file @
e4e02f91
This diff is collapsed.
Click to expand it.
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