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
876080ed
authored
Sep 21, 2018
by
Arnold Szabo
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
#4306 - code review fixes
parent
ae520a8c
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
33 additions
and
68 deletions
library/core/src/main/java/com/google/android/exoplayer2/text/subrip/SubripDecoder.java
library/core/src/main/java/com/google/android/exoplayer2/text/subrip/SubripDecoder.java
View file @
876080ed
...
@@ -29,7 +29,6 @@ import com.google.android.exoplayer2.util.ParsableByteArray;
...
@@ -29,7 +29,6 @@ import com.google.android.exoplayer2.util.ParsableByteArray;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.RetentionPolicy
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.regex.Matcher
;
import
java.util.regex.Matcher
;
import
java.util.regex.Pattern
;
import
java.util.regex.Pattern
;
...
@@ -81,6 +80,7 @@ public final class SubripDecoder extends SimpleSubtitleDecoder {
...
@@ -81,6 +80,7 @@ public final class SubripDecoder extends SimpleSubtitleDecoder {
@Override
@Override
protected
SubripSubtitle
decode
(
byte
[]
bytes
,
int
length
,
boolean
reset
)
{
protected
SubripSubtitle
decode
(
byte
[]
bytes
,
int
length
,
boolean
reset
)
{
ArrayList
<
Cue
>
cues
=
new
ArrayList
<>();
ArrayList
<
Cue
>
cues
=
new
ArrayList
<>();
ArrayList
<
String
>
tags
=
new
ArrayList
<>();
LongArray
cueTimesUs
=
new
LongArray
();
LongArray
cueTimesUs
=
new
LongArray
();
ParsableByteArray
subripData
=
new
ParsableByteArray
(
bytes
,
length
);
ParsableByteArray
subripData
=
new
ParsableByteArray
(
bytes
,
length
);
String
currentLine
;
String
currentLine
;
...
@@ -125,34 +125,25 @@ public final class SubripDecoder extends SimpleSubtitleDecoder {
...
@@ -125,34 +125,25 @@ public final class SubripDecoder extends SimpleSubtitleDecoder {
if
(
textBuilder
.
length
()
>
0
)
{
if
(
textBuilder
.
length
()
>
0
)
{
textBuilder
.
append
(
"<br>"
);
textBuilder
.
append
(
"<br>"
);
}
}
textBuilder
.
append
(
currentLine
.
trim
(
));
textBuilder
.
append
(
processLine
(
currentLine
,
tags
));
}
}
// Extract tags
Spanned
text
=
Html
.
fromHtml
(
textBuilder
.
toString
());
SubtitleTagResult
tagResult
=
extractTags
(
textBuilder
);
Spanned
text
=
Html
.
fromHtml
(
tagResult
.
cue
);
Cue
cue
=
null
;
Cue
cue
=
null
;
// Check if tags are present
boolean
alignTagFound
=
false
;
if
(
tagResult
.
tags
.
length
>
0
)
{
boolean
alignTagFound
=
false
;
// At end of this loop the clue must be created with the applied tags
// At end of this loop the clue must be created with the applied tags
for
(
String
tag
:
tagResult
.
tags
)
{
for
(
String
tag
:
tags
)
{
// Check if the tag is an alignment tag
// Check if the tag is an alignment tag
if
(
tag
.
matches
(
SUBRIP_ALIGNMENT_TAG
))
{
if
(
tag
.
matches
(
SUBRIP_ALIGNMENT_TAG
))
{
// Based on the specs, in case of the alignment tags only the first appearance counts
// Based on the specs, in case of the alignment tags only the first appearance counts
if
(
alignTagFound
)
continue
;
if
(
alignTagFound
)
continue
;
alignTagFound
=
true
;
alignTagFound
=
true
;
AlignmentResult
alignmentResult
=
getAlignmentValues
(
tag
);
cue
=
buildCue
(
text
,
tag
);
cue
=
new
Cue
(
text
,
Layout
.
Alignment
.
ALIGN_NORMAL
,
alignmentResult
.
line
,
Cue
.
LINE_TYPE_FRACTION
,
alignmentResult
.
lineAnchor
,
alignmentResult
.
position
,
alignmentResult
.
positionAnchor
,
Cue
.
DIMEN_UNSET
);
}
}
}
}
}
...
@@ -170,51 +161,57 @@ public final class SubripDecoder extends SimpleSubtitleDecoder {
...
@@ -170,51 +161,57 @@ public final class SubripDecoder extends SimpleSubtitleDecoder {
}
}
/**
/**
* Extracts the tags from the given {@code cue}
* Process the given line by first trimming it then extracting the tags from it
* <p>
* The pattern that is used to extract the tags is specified in SSA v4+ specs and
* The pattern that is used to extract the tags is specified in SSA v4+ specs and
* has the following form: "{\...}".
* has the following form: "{\...}".
* <p>
* <p>
* "All override codes appear within braces {}"
* "All override codes appear within braces {}"
* "All override codes are always preceded by a backslash \"
* "All override codes are always preceded by a backslash \"
*
*
* @param cue Cue text
* @param currentLine Current line
* @return {@link SubtitleTagResult} that holds new cue and also the extracted tags
* @param tags Extracted tags will be stored in this array list
* @return Processed line
*/
*/
private
S
ubtitleTagResult
extractTags
(
StringBuilder
cue
)
{
private
S
tring
processLine
(
String
currentLine
,
ArrayList
<
String
>
tags
)
{
StringBuilder
cueCopy
=
new
StringBuilder
(
cue
.
toString
());
// Trim line
List
<
String
>
tags
=
new
ArrayList
<>
();
String
trimmedLine
=
currentLine
.
trim
();
// Extract tags
int
replacedCharacters
=
0
;
int
replacedCharacters
=
0
;
StringBuilder
processedLine
=
new
StringBuilder
(
trimmedLine
);
Matcher
matcher
=
SUBRIP_TAG_PATTERN
.
matcher
(
processedLine
);
Matcher
matcher
=
SUBRIP_TAG_PATTERN
.
matcher
(
cue
.
toString
());
while
(
matcher
.
find
())
{
while
(
matcher
.
find
())
{
String
tag
=
matcher
.
group
();
String
tag
=
matcher
.
group
();
tags
.
add
(
tag
);
tags
.
add
(
tag
);
cueCopy
.
replace
(
matcher
.
start
()
-
replacedCharacters
,
matcher
.
end
()
-
replacedCharacters
,
""
);
processedLine
.
replace
(
matcher
.
start
()
-
replacedCharacters
,
matcher
.
end
()
-
replacedCharacters
,
""
);
replacedCharacters
+=
tag
.
length
();
replacedCharacters
+=
tag
.
length
();
}
}
return
new
SubtitleTagResult
(
tags
.
toArray
(
new
String
[
tags
.
size
()]),
cueCopy
.
toString
()
);
return
processedLine
.
toString
(
);
}
}
/**
/**
* Build a {@link Cue} based on the given text and tag
* <p>
* Match the alignment tag and calculate the line, position, position anchor accordingly
* Match the alignment tag and calculate the line, position, position anchor accordingly
*
*
<p>
* Based on SSA v4+ specs the alignment tag can have the following form: {\an[1-9},
* Based on SSA v4+ specs the alignment tag can have the following form: {\an[1-9},
* where the number specifies the direction (based on the numpad layout).
* where the number specifies the direction (based on the numpad layout).
* Note. older SSA scripts may contain tags like {\a1[1-9]} but these are based on
* Note. older SSA scripts may contain tags like {\a1[1-9]} but these are based on
* other direction rules, but multiple sources says that these are deprecated, so no support here either
* other direction rules, but multiple sources says that these are deprecated, so no support here either
*
*
* @param
t
ag Alignment tag
* @param
alignmentT
ag Alignment tag
* @return
{@link AlignmentResult} that holds the line, position, position anchor values
* @return
Built cue
*/
*/
private
AlignmentResult
getAlignmentValues
(
String
t
ag
)
{
private
Cue
buildCue
(
Spanned
text
,
String
alignmentT
ag
)
{
// Default values used for positioning the subtitle in case of align tags
// Default values used for positioning the subtitle in case of align tags
float
line
=
DEFAULT_END_FRACTION
,
position
=
DEFAULT_MID_FRACTION
;
float
line
=
DEFAULT_END_FRACTION
,
position
=
DEFAULT_MID_FRACTION
;
@Cue
.
AnchorType
int
positionAnchor
=
Cue
.
ANCHOR_TYPE_MIDDLE
;
@Cue
.
AnchorType
int
positionAnchor
=
Cue
.
ANCHOR_TYPE_MIDDLE
;
@Cue
.
AnchorType
int
lineAnchor
=
Cue
.
ANCHOR_TYPE_END
;
@Cue
.
AnchorType
int
lineAnchor
=
Cue
.
ANCHOR_TYPE_END
;
switch
(
t
ag
)
{
switch
(
alignmentT
ag
)
{
case
ALIGN_BOTTOM_LEFT:
case
ALIGN_BOTTOM_LEFT:
line
=
DEFAULT_END_FRACTION
;
line
=
DEFAULT_END_FRACTION
;
position
=
DEFAULT_START_FRACTION
;
position
=
DEFAULT_START_FRACTION
;
...
@@ -271,7 +268,7 @@ public final class SubripDecoder extends SimpleSubtitleDecoder {
...
@@ -271,7 +268,7 @@ public final class SubripDecoder extends SimpleSubtitleDecoder {
break
;
break
;
}
}
return
new
AlignmentResult
(
positionAnchor
,
position
,
lineAnchor
,
line
);
return
new
Cue
(
text
,
Layout
.
Alignment
.
ALIGN_NORMAL
,
line
,
Cue
.
LINE_TYPE_FRACTION
,
lineAnchor
,
position
,
positionAnchor
,
Cue
.
DIMEN_UNSET
);
}
}
private
static
long
parseTimecode
(
Matcher
matcher
,
int
groupOffset
)
{
private
static
long
parseTimecode
(
Matcher
matcher
,
int
groupOffset
)
{
...
@@ -281,36 +278,4 @@ public final class SubripDecoder extends SimpleSubtitleDecoder {
...
@@ -281,36 +278,4 @@ public final class SubripDecoder extends SimpleSubtitleDecoder {
timestampMs
+=
Long
.
parseLong
(
matcher
.
group
(
groupOffset
+
4
));
timestampMs
+=
Long
.
parseLong
(
matcher
.
group
(
groupOffset
+
4
));
return
timestampMs
*
1000
;
return
timestampMs
*
1000
;
}
}
/**
* Class that holds the tags, new clue after the tag extraction
*/
private
static
final
class
SubtitleTagResult
{
public
final
String
[]
tags
;
public
final
String
cue
;
public
SubtitleTagResult
(
String
[]
tags
,
String
cue
)
{
this
.
tags
=
tags
;
this
.
cue
=
cue
;
}
}
/**
* Class that holds the parsed and mapped alignment values (such as line,
* position and anchor type of line)
*/
private
static
final
class
AlignmentResult
{
public
@Cue
.
AnchorType
int
positionAnchor
;
public
@Cue
.
AnchorType
int
lineAnchor
;
public
float
position
,
line
;
public
AlignmentResult
(
@Cue
.
AnchorType
int
positionAnchor
,
float
position
,
@Cue
.
AnchorType
int
lineAnchor
,
float
line
)
{
this
.
positionAnchor
=
positionAnchor
;
this
.
position
=
position
;
this
.
line
=
line
;
this
.
lineAnchor
=
lineAnchor
;
}
}
}
}
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