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
ec69977a
authored
Mar 01, 2021
by
Abel Jimenez
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
ssa bold and italic
parent
71409c44
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
110 additions
and
7 deletions
demos/main/src/main/assets/media.exolist.json
library/core/src/main/java/com/google/android/exoplayer2/text/ssa/SsaDecoder.java
library/core/src/main/java/com/google/android/exoplayer2/text/ssa/SsaStyle.java
library/core/src/test/java/com/google/android/exoplayer2/text/ssa/SsaDecoderTest.java
testdata/src/test/assets/media/ssa/style_bold_italic
demos/main/src/main/assets/media.exolist.json
View file @
ec69977a
...
@@ -507,6 +507,13 @@
...
@@ -507,6 +507,13 @@
"subtitle_language"
:
"en"
"subtitle_language"
:
"en"
},
},
{
{
"name"
:
"SubStation Alpha Style"
,
"uri"
:
"https://storage.googleapis.com/exoplayer-test-media-1/gen-3/screens/dash-vod-single-segment/video-avc-baseline-480.mp4"
,
"subtitle_uri"
:
"https://drive.google.com/uc?export=download&id=16IrvtynQ6-ANRpRX7hU6xEQeFU91LmXl"
,
"subtitle_mime_type"
:
"text/x-ssa"
,
"subtitle_language"
:
"en"
},
{
"name"
:
"MPEG-4 Timed Text"
,
"name"
:
"MPEG-4 Timed Text"
,
"uri"
:
"https://storage.googleapis.com/exoplayer-test-media-1/mp4/dizzy-with-tx3g.mp4"
"uri"
:
"https://storage.googleapis.com/exoplayer-test-media-1/mp4/dizzy-with-tx3g.mp4"
}
}
...
...
library/core/src/main/java/com/google/android/exoplayer2/text/ssa/SsaDecoder.java
View file @
ec69977a
...
@@ -18,9 +18,11 @@ package com.google.android.exoplayer2.text.ssa;
...
@@ -18,9 +18,11 @@ package com.google.android.exoplayer2.text.ssa;
import
static
com
.
google
.
android
.
exoplayer2
.
text
.
Cue
.
LINE_TYPE_FRACTION
;
import
static
com
.
google
.
android
.
exoplayer2
.
text
.
Cue
.
LINE_TYPE_FRACTION
;
import
static
com
.
google
.
android
.
exoplayer2
.
util
.
Util
.
castNonNull
;
import
static
com
.
google
.
android
.
exoplayer2
.
util
.
Util
.
castNonNull
;
import
android.graphics.Typeface
;
import
android.text.Layout
;
import
android.text.Layout
;
import
android.text.SpannableString
;
import
android.text.SpannableString
;
import
android.text.style.ForegroundColorSpan
;
import
android.text.style.ForegroundColorSpan
;
import
android.text.style.StyleSpan
;
import
androidx.annotation.Nullable
;
import
androidx.annotation.Nullable
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.text.Cue
;
import
com.google.android.exoplayer2.text.Cue
;
...
@@ -319,6 +321,27 @@ public final class SsaDecoder extends SimpleSubtitleDecoder {
...
@@ -319,6 +321,27 @@ public final class SsaDecoder extends SimpleSubtitleDecoder {
style
.
fontSize
/
screenHeight
,
style
.
fontSize
/
screenHeight
,
Cue
.
TEXT_SIZE_TYPE_FRACTIONAL_IGNORE_PADDING
);
Cue
.
TEXT_SIZE_TYPE_FRACTIONAL_IGNORE_PADDING
);
}
}
if
(
style
.
bold
&&
style
.
italic
)
{
spannableText
.
setSpan
(
new
StyleSpan
(
Typeface
.
BOLD_ITALIC
),
0
,
spannableText
.
length
(),
SpannableString
.
SPAN_EXCLUSIVE_EXCLUSIVE
);
}
else
if
(
style
.
bold
){
spannableText
.
setSpan
(
new
StyleSpan
(
Typeface
.
BOLD
),
0
,
spannableText
.
length
(),
SpannableString
.
SPAN_EXCLUSIVE_EXCLUSIVE
);
}
else
if
(
style
.
italic
){
spannableText
.
setSpan
(
new
StyleSpan
(
Typeface
.
ITALIC
),
0
,
spannableText
.
length
(),
SpannableString
.
SPAN_EXCLUSIVE_EXCLUSIVE
);
}
}
}
@SsaStyle
.
SsaAlignment
int
alignment
;
@SsaStyle
.
SsaAlignment
int
alignment
;
...
...
library/core/src/main/java/com/google/android/exoplayer2/text/ssa/SsaStyle.java
View file @
ec69977a
...
@@ -92,16 +92,22 @@ import java.util.regex.Pattern;
...
@@ -92,16 +92,22 @@ import java.util.regex.Pattern;
@SsaAlignment
public
final
int
alignment
;
@SsaAlignment
public
final
int
alignment
;
@Nullable
@ColorInt
public
final
Integer
primaryColor
;
@Nullable
@ColorInt
public
final
Integer
primaryColor
;
public
final
float
fontSize
;
public
final
float
fontSize
;
public
final
boolean
bold
;
public
final
boolean
italic
;
private
SsaStyle
(
private
SsaStyle
(
String
name
,
String
name
,
@SsaAlignment
int
alignment
,
@SsaAlignment
int
alignment
,
@Nullable
@ColorInt
Integer
primaryColor
,
@Nullable
@ColorInt
Integer
primaryColor
,
float
fontSize
)
{
float
fontSize
,
boolean
bold
,
boolean
italic
)
{
this
.
name
=
name
;
this
.
name
=
name
;
this
.
alignment
=
alignment
;
this
.
alignment
=
alignment
;
this
.
primaryColor
=
primaryColor
;
this
.
primaryColor
=
primaryColor
;
this
.
fontSize
=
fontSize
;
this
.
fontSize
=
fontSize
;
this
.
bold
=
bold
;
this
.
italic
=
italic
;
}
}
@Nullable
@Nullable
...
@@ -121,7 +127,9 @@ import java.util.regex.Pattern;
...
@@ -121,7 +127,9 @@ import java.util.regex.Pattern;
styleValues
[
format
.
nameIndex
].
trim
(),
styleValues
[
format
.
nameIndex
].
trim
(),
parseAlignment
(
styleValues
[
format
.
alignmentIndex
].
trim
()),
parseAlignment
(
styleValues
[
format
.
alignmentIndex
].
trim
()),
parseColor
(
styleValues
[
format
.
primaryColorIndex
].
trim
()),
parseColor
(
styleValues
[
format
.
primaryColorIndex
].
trim
()),
parseFontSize
(
styleValues
[
format
.
fontSizeIndex
].
trim
()));
parseFontSize
(
styleValues
[
format
.
fontSizeIndex
].
trim
()),
parseBold
(
styleValues
[
format
.
boldIndex
].
trim
()),
parseItalic
(
styleValues
[
format
.
italicIndex
].
trim
()));
}
catch
(
RuntimeException
e
)
{
}
catch
(
RuntimeException
e
)
{
Log
.
w
(
TAG
,
"Skipping malformed 'Style:' line: '"
+
styleLine
+
"'"
,
e
);
Log
.
w
(
TAG
,
"Skipping malformed 'Style:' line: '"
+
styleLine
+
"'"
,
e
);
return
null
;
return
null
;
...
@@ -207,6 +215,36 @@ import java.util.regex.Pattern;
...
@@ -207,6 +215,36 @@ import java.util.regex.Pattern;
}
}
}
}
private
static
boolean
parseBold
(
String
bold
)
{
try
{
int
boldFlag
=
Integer
.
parseInt
(
bold
);
if
(
boldFlag
==
1
||
boldFlag
==
-
1
){
return
true
;
}
else
{
return
false
;
}
}
catch
(
NumberFormatException
e
)
{
Log
.
w
(
TAG
,
"Failed to parse bold: '"
+
bold
+
"'"
,
e
);
return
false
;
}
}
private
static
boolean
parseItalic
(
String
italic
)
{
try
{
int
italicFlag
=
Integer
.
parseInt
(
italic
);
if
(
italicFlag
==
1
||
italicFlag
==
-
1
){
return
true
;
}
else
{
return
false
;
}
}
catch
(
NumberFormatException
e
)
{
Log
.
w
(
TAG
,
"Failed to parse italic: '"
+
italic
+
"'"
,
e
);
return
false
;
}
}
/**
/**
* Represents a {@code Format:} line from the {@code [V4+ Styles]} section
* Represents a {@code Format:} line from the {@code [V4+ Styles]} section
*
*
...
@@ -219,6 +257,8 @@ import java.util.regex.Pattern;
...
@@ -219,6 +257,8 @@ import java.util.regex.Pattern;
public
final
int
alignmentIndex
;
public
final
int
alignmentIndex
;
public
final
int
primaryColorIndex
;
public
final
int
primaryColorIndex
;
public
final
int
fontSizeIndex
;
public
final
int
fontSizeIndex
;
public
final
int
boldIndex
;
public
final
int
italicIndex
;
public
final
int
length
;
public
final
int
length
;
private
Format
(
private
Format
(
...
@@ -226,11 +266,15 @@ import java.util.regex.Pattern;
...
@@ -226,11 +266,15 @@ import java.util.regex.Pattern;
int
alignmentIndex
,
int
alignmentIndex
,
int
primaryColorIndex
,
int
primaryColorIndex
,
int
fontSizeIndex
,
int
fontSizeIndex
,
int
boldIndex
,
int
italicIndex
,
int
length
)
{
int
length
)
{
this
.
nameIndex
=
nameIndex
;
this
.
nameIndex
=
nameIndex
;
this
.
alignmentIndex
=
alignmentIndex
;
this
.
alignmentIndex
=
alignmentIndex
;
this
.
primaryColorIndex
=
primaryColorIndex
;
this
.
primaryColorIndex
=
primaryColorIndex
;
this
.
fontSizeIndex
=
fontSizeIndex
;
this
.
fontSizeIndex
=
fontSizeIndex
;
this
.
boldIndex
=
boldIndex
;
this
.
italicIndex
=
italicIndex
;
this
.
length
=
length
;
this
.
length
=
length
;
}
}
...
@@ -245,6 +289,8 @@ import java.util.regex.Pattern;
...
@@ -245,6 +289,8 @@ import java.util.regex.Pattern;
int
alignmentIndex
=
C
.
INDEX_UNSET
;
int
alignmentIndex
=
C
.
INDEX_UNSET
;
int
primaryColorIndex
=
C
.
INDEX_UNSET
;
int
primaryColorIndex
=
C
.
INDEX_UNSET
;
int
fontSizeIndex
=
C
.
INDEX_UNSET
;
int
fontSizeIndex
=
C
.
INDEX_UNSET
;
int
boldIndex
=
C
.
INDEX_UNSET
;
int
italicIndex
=
C
.
INDEX_UNSET
;
String
[]
keys
=
String
[]
keys
=
TextUtils
.
split
(
styleFormatLine
.
substring
(
SsaDecoder
.
FORMAT_LINE_PREFIX
.
length
()),
","
);
TextUtils
.
split
(
styleFormatLine
.
substring
(
SsaDecoder
.
FORMAT_LINE_PREFIX
.
length
()),
","
);
for
(
int
i
=
0
;
i
<
keys
.
length
;
i
++)
{
for
(
int
i
=
0
;
i
<
keys
.
length
;
i
++)
{
...
@@ -261,10 +307,16 @@ import java.util.regex.Pattern;
...
@@ -261,10 +307,16 @@ import java.util.regex.Pattern;
case
"fontsize"
:
case
"fontsize"
:
fontSizeIndex
=
i
;
fontSizeIndex
=
i
;
break
;
break
;
case
"bold"
:
boldIndex
=
i
;
break
;
case
"italic"
:
italicIndex
=
i
;
break
;
}
}
}
}
return
nameIndex
!=
C
.
INDEX_UNSET
return
nameIndex
!=
C
.
INDEX_UNSET
?
new
Format
(
nameIndex
,
alignmentIndex
,
primaryColorIndex
,
fontSizeIndex
,
keys
.
length
)
?
new
Format
(
nameIndex
,
alignmentIndex
,
primaryColorIndex
,
fontSizeIndex
,
boldIndex
,
italicIndex
,
keys
.
length
)
:
null
;
:
null
;
}
}
}
}
...
...
library/core/src/test/java/com/google/android/exoplayer2/text/ssa/SsaDecoderTest.java
View file @
ec69977a
...
@@ -19,6 +19,7 @@ import static com.google.common.truth.Truth.assertThat;
...
@@ -19,6 +19,7 @@ import static com.google.common.truth.Truth.assertThat;
import
static
com
.
google
.
common
.
truth
.
Truth
.
assertWithMessage
;
import
static
com
.
google
.
common
.
truth
.
Truth
.
assertWithMessage
;
import
android.graphics.Color
;
import
android.graphics.Color
;
import
android.graphics.Typeface
;
import
android.text.Layout
;
import
android.text.Layout
;
import
android.text.Spanned
;
import
android.text.Spanned
;
import
androidx.test.core.app.ApplicationProvider
;
import
androidx.test.core.app.ApplicationProvider
;
...
@@ -49,6 +50,7 @@ public final class SsaDecoderTest {
...
@@ -49,6 +50,7 @@ public final class SsaDecoderTest {
private
static
final
String
POSITIONS_WITHOUT_PLAYRES
=
"media/ssa/positioning_without_playres"
;
private
static
final
String
POSITIONS_WITHOUT_PLAYRES
=
"media/ssa/positioning_without_playres"
;
private
static
final
String
STYLE_COLORS
=
"media/ssa/style_colors"
;
private
static
final
String
STYLE_COLORS
=
"media/ssa/style_colors"
;
private
static
final
String
STYLE_FONT_SIZE
=
"media/ssa/style_font_size"
;
private
static
final
String
STYLE_FONT_SIZE
=
"media/ssa/style_font_size"
;
private
static
final
String
STYLE_BOLD_ITALIC
=
"media/ssa/style_bold_italic"
;
@Test
@Test
public
void
decodeEmpty
()
throws
IOException
{
public
void
decodeEmpty
()
throws
IOException
{
...
@@ -335,6 +337,24 @@ public final class SsaDecoderTest {
...
@@ -335,6 +337,24 @@ public final class SsaDecoderTest {
assertThat
(
secondCue
.
textSizeType
).
isEqualTo
(
Cue
.
TEXT_SIZE_TYPE_FRACTIONAL_IGNORE_PADDING
);
assertThat
(
secondCue
.
textSizeType
).
isEqualTo
(
Cue
.
TEXT_SIZE_TYPE_FRACTIONAL_IGNORE_PADDING
);
}
}
@Test
public
void
decodeBoldItalic
()
throws
IOException
{
SsaDecoder
decoder
=
new
SsaDecoder
();
byte
[]
bytes
=
TestUtil
.
getByteArray
(
ApplicationProvider
.
getApplicationContext
(),
STYLE_BOLD_ITALIC
);
Subtitle
subtitle
=
decoder
.
decode
(
bytes
,
bytes
.
length
,
false
);
assertThat
(
subtitle
.
getEventTimeCount
()).
isEqualTo
(
6
);
Spanned
firstCueText
=
(
Spanned
)
Iterables
.
getOnlyElement
(
subtitle
.
getCues
(
subtitle
.
getEventTime
(
0
))).
text
;
SpannedSubject
.
assertThat
(
firstCueText
).
hasBoldSpanBetween
(
0
,
firstCueText
.
length
());
Spanned
secondCueText
=
(
Spanned
)
Iterables
.
getOnlyElement
(
subtitle
.
getCues
(
subtitle
.
getEventTime
(
2
))).
text
;
SpannedSubject
.
assertThat
(
secondCueText
).
hasItalicSpanBetween
(
0
,
secondCueText
.
length
());
Spanned
thirdCueText
=
(
Spanned
)
Iterables
.
getOnlyElement
(
subtitle
.
getCues
(
subtitle
.
getEventTime
(
4
))).
text
;
SpannedSubject
.
assertThat
(
thirdCueText
).
hasBoldItalicSpanBetween
(
0
,
thirdCueText
.
length
());
}
private
static
void
assertTypicalCue1
(
Subtitle
subtitle
,
int
eventIndex
)
{
private
static
void
assertTypicalCue1
(
Subtitle
subtitle
,
int
eventIndex
)
{
assertThat
(
subtitle
.
getEventTime
(
eventIndex
)).
isEqualTo
(
0
);
assertThat
(
subtitle
.
getEventTime
(
eventIndex
)).
isEqualTo
(
0
);
assertThat
(
subtitle
.
getCues
(
subtitle
.
getEventTime
(
eventIndex
)).
get
(
0
).
text
.
toString
())
assertThat
(
subtitle
.
getCues
(
subtitle
.
getEventTime
(
eventIndex
)).
get
(
0
).
text
.
toString
())
...
...
testdata/src/test/assets/media/ssa/style_bold_italic
View file @
ec69977a
...
@@ -9,11 +9,12 @@ PlayResY: 720
...
@@ -9,11 +9,12 @@ PlayResY: 720
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: FontBold ,Roboto,50,&H000000FF,&H000000FF,&H00000000,&H00000000,-1,0,0,0,100,100,0,0,1,3,0,2,50,50,70,1
Style: FontBold ,Roboto,50,&H000000FF,&H000000FF,&H00000000,&H00000000,-1,0,0,0,100,100,0,0,1,3,0,2,50,50,70,1
Style: FontItalic ,Roboto,50,&H000000FF,&H000000FF,&H00000000,&H00000000,0,-1,0,0,100,100,0,0,1,3,0,2,50,50,70,1
Style: FontItalic ,Roboto,50,&H000000FF,&H000000FF,&H00000000,&H00000000,0,-1,0,0,100,100,0,0,1,3,0,2,50,50,70,1
Style: Font
Italic
,Roboto,50,&H000000FF,&H000000FF,&H00000000,&H00000000,-1,-1,0,0,100,100,0,0,1,3,0,2,50,50,70,1
Style: Font
BoldItalic
,Roboto,50,&H000000FF,&H000000FF,&H00000000,&H00000000,-1,-1,0,0,100,100,0,0,1,3,0,2,50,50,70,1
[Events]
[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 0,0:00:00.95,0:00:03.11,FontSizeSmall ,Arnold,0,0,0,,First line with font size 30.
Dialogue: 0,0:00:01.00,0:00:03.00,FontBold ,Abel,0,0,0,,First line with Bold.
Dialogue: 0,0:00:08.50,0:00:11.50,FontSizeBig ,Arnold,0,0,0,,Second line with font size 72.2.
Dialogue: 0,0:00:05.00,0:00:07.00,FontItalic ,Abel,0,0,0,,Second line with Italic.
\ No newline at end of file
Dialogue: 0,0:00:09.00,0:00:11.00,FontBoldItalic ,Abel,0,0,0,,Third line with Bold Italic.
\ No newline at end of file
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