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
a85a1696
authored
May 28, 2015
by
Oliver Woodman
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Simplify the demo app.
parent
b806109c
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
357 additions
and
448 deletions
demo/src/main/java/com/google/android/exoplayer/demo/DemoUtil.java
demo/src/main/java/com/google/android/exoplayer/demo/PlayerActivity.java
demo/src/main/java/com/google/android/exoplayer/demo/Samples.java
demo/src/main/java/com/google/android/exoplayer/demo/SmoothStreamingTestMediaDrmCallback.java
demo/src/main/java/com/google/android/exoplayer/demo/WidevineTestMediaDrmCallback.java
demo/src/main/java/com/google/android/exoplayer/demo/player/DashRendererBuilder.java
demo/src/main/java/com/google/android/exoplayer/demo/player/DebugTrackRenderer.java
demo/src/main/java/com/google/android/exoplayer/demo/player/DemoPlayer.java
demo/src/main/java/com/google/android/exoplayer/demo/player/ExtractorRendererBuilder.java
demo/src/main/java/com/google/android/exoplayer/demo/player/HlsRendererBuilder.java
demo/src/main/java/com/google/android/exoplayer/demo/player/SmoothStreamingRendererBuilder.java
library/src/main/java/com/google/android/exoplayer/drm/StreamingDrmSessionManager.java
demo/src/main/java/com/google/android/exoplayer/demo/player/UnsupportedDrmException.java → library/src/main/java/com/google/android/exoplayer/drm/UnsupportedDrmException.java
library/src/main/java/com/google/android/exoplayer/util/DebugTextViewHelper.java
library/src/main/java/com/google/android/exoplayer/util/Util.java
demo/src/main/java/com/google/android/exoplayer/demo/DemoUtil.java
deleted
100644 → 0
View file @
b806109c
/*
* 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
.
demo
;
import
java.io.BufferedInputStream
;
import
java.io.BufferedOutputStream
;
import
java.io.ByteArrayOutputStream
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.net.CookieHandler
;
import
java.net.CookieManager
;
import
java.net.CookiePolicy
;
import
java.net.HttpURLConnection
;
import
java.net.URL
;
import
java.util.Map
;
/**
* Utility methods for the demo application.
*/
public
class
DemoUtil
{
public
static
final
int
TYPE_DASH
=
0
;
public
static
final
int
TYPE_SS
=
1
;
public
static
final
int
TYPE_HLS
=
2
;
public
static
final
int
TYPE_MP4
=
3
;
public
static
final
int
TYPE_MP3
=
4
;
public
static
final
int
TYPE_M4A
=
5
;
public
static
final
int
TYPE_WEBM
=
6
;
public
static
final
int
TYPE_TS
=
7
;
public
static
final
int
TYPE_AAC
=
8
;
private
static
final
CookieManager
defaultCookieManager
;
static
{
defaultCookieManager
=
new
CookieManager
();
defaultCookieManager
.
setCookiePolicy
(
CookiePolicy
.
ACCEPT_ORIGINAL_SERVER
);
}
public
static
byte
[]
executePost
(
String
url
,
byte
[]
data
,
Map
<
String
,
String
>
requestProperties
)
throws
IOException
{
HttpURLConnection
urlConnection
=
null
;
try
{
urlConnection
=
(
HttpURLConnection
)
new
URL
(
url
).
openConnection
();
urlConnection
.
setRequestMethod
(
"POST"
);
urlConnection
.
setDoOutput
(
data
!=
null
);
urlConnection
.
setDoInput
(
true
);
if
(
requestProperties
!=
null
)
{
for
(
Map
.
Entry
<
String
,
String
>
requestProperty
:
requestProperties
.
entrySet
())
{
urlConnection
.
setRequestProperty
(
requestProperty
.
getKey
(),
requestProperty
.
getValue
());
}
}
if
(
data
!=
null
)
{
OutputStream
out
=
new
BufferedOutputStream
(
urlConnection
.
getOutputStream
());
out
.
write
(
data
);
out
.
close
();
}
InputStream
in
=
new
BufferedInputStream
(
urlConnection
.
getInputStream
());
return
convertInputStreamToByteArray
(
in
);
}
finally
{
if
(
urlConnection
!=
null
)
{
urlConnection
.
disconnect
();
}
}
}
private
static
byte
[]
convertInputStreamToByteArray
(
InputStream
inputStream
)
throws
IOException
{
byte
[]
bytes
=
null
;
ByteArrayOutputStream
bos
=
new
ByteArrayOutputStream
();
byte
data
[]
=
new
byte
[
1024
];
int
count
;
while
((
count
=
inputStream
.
read
(
data
))
!=
-
1
)
{
bos
.
write
(
data
,
0
,
count
);
}
bos
.
flush
();
bos
.
close
();
inputStream
.
close
();
bytes
=
bos
.
toByteArray
();
return
bytes
;
}
public
static
void
setDefaultCookieManager
()
{
CookieHandler
currentHandler
=
CookieHandler
.
getDefault
();
if
(
currentHandler
!=
defaultCookieManager
)
{
CookieHandler
.
setDefault
(
defaultCookieManager
);
}
}
}
demo/src/main/java/com/google/android/exoplayer/demo/PlayerActivity.java
View file @
a85a1696
...
...
@@ -25,7 +25,7 @@ import com.google.android.exoplayer.demo.player.DemoPlayer.RendererBuilder;
import
com.google.android.exoplayer.demo.player.ExtractorRendererBuilder
;
import
com.google.android.exoplayer.demo.player.HlsRendererBuilder
;
import
com.google.android.exoplayer.demo.player.SmoothStreamingRendererBuilder
;
import
com.google.android.exoplayer.d
emo.player
.UnsupportedDrmException
;
import
com.google.android.exoplayer.d
rm
.UnsupportedDrmException
;
import
com.google.android.exoplayer.extractor.mp3.Mp3Extractor
;
import
com.google.android.exoplayer.extractor.mp4.Mp4Extractor
;
import
com.google.android.exoplayer.extractor.ts.AdtsExtractor
;
...
...
@@ -37,6 +37,7 @@ import com.google.android.exoplayer.metadata.TxxxMetadata;
import
com.google.android.exoplayer.text.CaptionStyleCompat
;
import
com.google.android.exoplayer.text.Cue
;
import
com.google.android.exoplayer.text.SubtitleLayout
;
import
com.google.android.exoplayer.util.DebugTextViewHelper
;
import
com.google.android.exoplayer.util.Util
;
import
com.google.android.exoplayer.util.VerboseLogUtil
;
...
...
@@ -65,6 +66,9 @@ import android.widget.PopupMenu.OnMenuItemClickListener;
import
android.widget.TextView
;
import
android.widget.Toast
;
import
java.net.CookieHandler
;
import
java.net.CookieManager
;
import
java.net.CookiePolicy
;
import
java.util.List
;
import
java.util.Map
;
...
...
@@ -75,14 +79,30 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback,
DemoPlayer
.
Listener
,
DemoPlayer
.
CaptionListener
,
DemoPlayer
.
Id3MetadataListener
,
AudioCapabilitiesReceiver
.
Listener
{
public
static
final
int
TYPE_DASH
=
0
;
public
static
final
int
TYPE_SS
=
1
;
public
static
final
int
TYPE_HLS
=
2
;
public
static
final
int
TYPE_MP4
=
3
;
public
static
final
int
TYPE_MP3
=
4
;
public
static
final
int
TYPE_FMP4
=
5
;
public
static
final
int
TYPE_WEBM
=
6
;
public
static
final
int
TYPE_TS
=
7
;
public
static
final
int
TYPE_AAC
=
8
;
public
static
final
int
TYPE_M4A
=
9
;
public
static
final
String
CONTENT_TYPE_EXTRA
=
"content_type"
;
public
static
final
String
CONTENT_ID_EXTRA
=
"content_id"
;
private
static
final
String
TAG
=
"PlayerActivity"
;
private
static
final
int
MENU_GROUP_TRACKS
=
1
;
private
static
final
int
ID_OFFSET
=
2
;
private
static
final
CookieManager
defaultCookieManager
;
static
{
defaultCookieManager
=
new
CookieManager
();
defaultCookieManager
.
setCookiePolicy
(
CookiePolicy
.
ACCEPT_ORIGINAL_SERVER
);
}
private
EventLogger
eventLogger
;
private
MediaController
mediaController
;
private
View
debugRootView
;
...
...
@@ -97,6 +117,7 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback,
private
Button
retryButton
;
private
DemoPlayer
player
;
private
DebugTextViewHelper
debugViewHelper
;
private
boolean
playerNeedsPrepare
;
private
long
playerPosition
;
...
...
@@ -162,7 +183,10 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback,
audioButton
=
(
Button
)
findViewById
(
R
.
id
.
audio_controls
);
textButton
=
(
Button
)
findViewById
(
R
.
id
.
text_controls
);
DemoUtil
.
setDefaultCookieManager
();
CookieHandler
currentHandler
=
CookieHandler
.
getDefault
();
if
(
currentHandler
!=
defaultCookieManager
)
{
CookieHandler
.
setDefault
(
defaultCookieManager
);
}
}
@Override
...
...
@@ -220,31 +244,26 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback,
private
RendererBuilder
getRendererBuilder
()
{
String
userAgent
=
Util
.
getUserAgent
(
this
,
"ExoPlayerDemo"
);
switch
(
contentType
)
{
case
DemoUtil
.
TYPE_SS
:
case
TYPE_SS:
return
new
SmoothStreamingRendererBuilder
(
this
,
userAgent
,
contentUri
.
toString
(),
new
SmoothStreamingTestMediaDrmCallback
()
,
debugTextView
);
case
DemoUtil
.
TYPE_DASH
:
new
SmoothStreamingTestMediaDrmCallback
());
case
TYPE_DASH:
return
new
DashRendererBuilder
(
this
,
userAgent
,
contentUri
.
toString
(),
new
WidevineTestMediaDrmCallback
(
contentId
),
debugTextView
,
audioCapabilities
);
case
DemoUtil
.
TYPE_HLS
:
return
new
HlsRendererBuilder
(
this
,
userAgent
,
contentUri
.
toString
(),
debugTextView
,
audioCapabilities
);
case
DemoUtil
.
TYPE_M4A
:
// There are no file format differences between M4A and MP4.
case
DemoUtil
.
TYPE_MP4
:
return
new
ExtractorRendererBuilder
(
this
,
userAgent
,
contentUri
,
debugTextView
,
new
Mp4Extractor
());
case
DemoUtil
.
TYPE_MP3
:
return
new
ExtractorRendererBuilder
(
this
,
userAgent
,
contentUri
,
debugTextView
,
new
Mp3Extractor
());
case
DemoUtil
.
TYPE_TS
:
return
new
ExtractorRendererBuilder
(
this
,
userAgent
,
contentUri
,
debugTextView
,
new
WidevineTestMediaDrmCallback
(
contentId
),
audioCapabilities
);
case
TYPE_HLS:
return
new
HlsRendererBuilder
(
this
,
userAgent
,
contentUri
.
toString
(),
audioCapabilities
);
case
TYPE_M4A:
// There are no file format differences between M4A and MP4.
case
TYPE_MP4:
return
new
ExtractorRendererBuilder
(
this
,
userAgent
,
contentUri
,
new
Mp4Extractor
());
case
TYPE_MP3:
return
new
ExtractorRendererBuilder
(
this
,
userAgent
,
contentUri
,
new
Mp3Extractor
());
case
TYPE_TS:
return
new
ExtractorRendererBuilder
(
this
,
userAgent
,
contentUri
,
new
TsExtractor
(
0
,
audioCapabilities
));
case
DemoUtil
.
TYPE_AAC
:
return
new
ExtractorRendererBuilder
(
this
,
userAgent
,
contentUri
,
debugTextView
,
new
AdtsExtractor
());
case
DemoUtil
.
TYPE_WEBM
:
return
new
ExtractorRendererBuilder
(
this
,
userAgent
,
contentUri
,
debugTextView
,
new
WebmExtractor
());
case
TYPE_AAC:
return
new
ExtractorRendererBuilder
(
this
,
userAgent
,
contentUri
,
new
AdtsExtractor
());
case
TYPE_WEBM:
return
new
ExtractorRendererBuilder
(
this
,
userAgent
,
contentUri
,
new
WebmExtractor
());
default
:
throw
new
IllegalStateException
(
"Unsupported type: "
+
contentType
);
}
...
...
@@ -265,6 +284,8 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback,
player
.
addListener
(
eventLogger
);
player
.
setInfoListener
(
eventLogger
);
player
.
setInternalErrorListener
(
eventLogger
);
debugViewHelper
=
new
DebugTextViewHelper
(
player
,
debugTextView
);
debugViewHelper
.
start
();
}
if
(
playerNeedsPrepare
)
{
player
.
prepare
();
...
...
@@ -277,6 +298,8 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback,
private
void
releasePlayer
()
{
if
(
player
!=
null
)
{
debugViewHelper
.
stop
();
debugViewHelper
=
null
;
playerPosition
=
player
.
getCurrentPosition
();
player
.
release
();
player
=
null
;
...
...
@@ -322,11 +345,9 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback,
if
(
e
instanceof
UnsupportedDrmException
)
{
// Special case DRM failures.
UnsupportedDrmException
unsupportedDrmException
=
(
UnsupportedDrmException
)
e
;
int
stringId
=
unsupportedDrmException
.
reason
==
UnsupportedDrmException
.
REASON_NO_DRM
?
R
.
string
.
drm_error_not_supported
int
stringId
=
Util
.
SDK_INT
<
18
?
R
.
string
.
drm_error_not_supported
:
unsupportedDrmException
.
reason
==
UnsupportedDrmException
.
REASON_UNSUPPORTED_SCHEME
?
R
.
string
.
drm_error_unsupported_scheme
:
R
.
string
.
drm_error_unknown
;
?
R
.
string
.
drm_error_unsupported_scheme
:
R
.
string
.
drm_error_unknown
;
Toast
.
makeText
(
getApplicationContext
(),
stringId
,
Toast
.
LENGTH_LONG
).
show
();
}
playerNeedsPrepare
=
true
;
...
...
demo/src/main/java/com/google/android/exoplayer/demo/Samples.java
View file @
a85a1696
...
...
@@ -47,12 +47,12 @@ import java.util.Locale;
"http://www.youtube.com/api/manifest/dash/id/bf5bb2419360daf1/source/youtube?"
+
"as=fmp4_audio_clear,fmp4_sd_hd_clear&sparams=ip,ipbits,expire,source,id,as&ip=0.0.0.0&"
+
"ipbits=0&expire=19000000000&signature=51AF5F39AB0CEC3E5497CD9C900EBFEAECCCB5C7."
+
"8506521BFC350652163895D4C26DEE124209AA9E&key=ik0"
,
DemoUtil
.
TYPE_DASH
),
+
"8506521BFC350652163895D4C26DEE124209AA9E&key=ik0"
,
PlayerActivity
.
TYPE_DASH
),
new
Sample
(
"Google Play"
,
"http://www.youtube.com/api/manifest/dash/id/3aa39fa2cc27967f/source/youtube?"
+
"as=fmp4_audio_clear,fmp4_sd_hd_clear&sparams=ip,ipbits,expire,source,id,as&ip=0.0.0.0&"
+
"ipbits=0&expire=19000000000&signature=A2716F75795F5D2AF0E88962FFCD10DB79384F29."
+
"84308FF04844498CE6FBCE4731507882B8307798&key=ik0"
,
DemoUtil
.
TYPE_DASH
),
+
"84308FF04844498CE6FBCE4731507882B8307798&key=ik0"
,
PlayerActivity
.
TYPE_DASH
),
};
public
static
final
Sample
[]
YOUTUBE_DASH_WEBM
=
new
Sample
[]
{
...
...
@@ -60,21 +60,21 @@ import java.util.Locale;
"http://www.youtube.com/api/manifest/dash/id/bf5bb2419360daf1/source/youtube?"
+
"as=fmp4_audio_clear,webm2_sd_hd_clear&sparams=ip,ipbits,expire,source,id,as&ip=0.0.0.0&"
+
"ipbits=0&expire=19000000000&signature=249B04F79E984D7F86B4D8DB48AE6FAF41C17AB3."
+
"7B9F0EC0505E1566E59B8E488E9419F253DDF413&key=ik0"
,
DemoUtil
.
TYPE_DASH
),
+
"7B9F0EC0505E1566E59B8E488E9419F253DDF413&key=ik0"
,
PlayerActivity
.
TYPE_DASH
),
new
Sample
(
"Google Play"
,
"http://www.youtube.com/api/manifest/dash/id/3aa39fa2cc27967f/source/youtube?"
+
"as=fmp4_audio_clear,webm2_sd_hd_clear&sparams=ip,ipbits,expire,source,id,as&ip=0.0.0.0&"
+
"ipbits=0&expire=19000000000&signature=B1C2A74783AC1CC4865EB312D7DD2D48230CC9FD."
+
"BD153B9882175F1F94BFE5141A5482313EA38E8D&key=ik0"
,
DemoUtil
.
TYPE_DASH
),
+
"BD153B9882175F1F94BFE5141A5482313EA38E8D&key=ik0"
,
PlayerActivity
.
TYPE_DASH
),
};
public
static
final
Sample
[]
SMOOTHSTREAMING
=
new
Sample
[]
{
new
Sample
(
"Super speed"
,
"http://playready.directtaps.net/smoothstreaming/SSWSS720H264/SuperSpeedway_720.ism"
,
DemoUtil
.
TYPE_SS
),
PlayerActivity
.
TYPE_SS
),
new
Sample
(
"Super speed (PlayReady)"
,
"http://playready.directtaps.net/smoothstreaming/SSWSS720H264PR/SuperSpeedway_720.ism"
,
DemoUtil
.
TYPE_SS
),
PlayerActivity
.
TYPE_SS
),
};
public
static
final
Sample
[]
WIDEVINE_GTS
=
new
Sample
[]
{
...
...
@@ -82,72 +82,72 @@ import java.util.Locale;
"http://www.youtube.com/api/manifest/dash/id/d286538032258a1c/source/youtube?"
+
"as=fmp4_audio_cenc,fmp4_sd_hd_cenc&sparams=ip,ipbits,expire,source,id,as&ip=0.0.0.0"
+
"&ipbits=0&expire=19000000000&signature=477CF7D478BE26C205045D507E9358F85F84C065."
+
"8971631EB657BC33EC2F48A2FF4211956760C3E9&key=ik0"
,
DemoUtil
.
TYPE_DASH
),
+
"8971631EB657BC33EC2F48A2FF4211956760C3E9&key=ik0"
,
PlayerActivity
.
TYPE_DASH
),
new
Sample
(
"WV: HDCP not required"
,
"48fcc369939ac96c"
,
"http://www.youtube.com/api/manifest/dash/id/48fcc369939ac96c/source/youtube?"
+
"as=fmp4_audio_cenc,fmp4_sd_hd_cenc&sparams=ip,ipbits,expire,source,id,as&ip=0.0.0.0"
+
"&ipbits=0&expire=19000000000&signature=171DAE48D00B5BE7434BC1A9F84DAE0463C7EA7A."
+
"0925B4DBB5605BEE9F5D088C48F25F5108E96191&key=ik0"
,
DemoUtil
.
TYPE_DASH
),
+
"0925B4DBB5605BEE9F5D088C48F25F5108E96191&key=ik0"
,
PlayerActivity
.
TYPE_DASH
),
new
Sample
(
"WV: HDCP required"
,
"e06c39f1151da3df"
,
"http://www.youtube.com/api/manifest/dash/id/e06c39f1151da3df/source/youtube?"
+
"as=fmp4_audio_cenc,fmp4_sd_hd_cenc&sparams=ip,ipbits,expire,source,id,as&ip=0.0.0.0"
+
"&ipbits=0&expire=19000000000&signature=8D3B8AF4E3F72B7F127C8D0D39B7AFCF37B30519."
+
"A118BADEBF3582AD2CC257B0EE6E579C6955D8AA&key=ik0"
,
DemoUtil
.
TYPE_DASH
),
+
"A118BADEBF3582AD2CC257B0EE6E579C6955D8AA&key=ik0"
,
PlayerActivity
.
TYPE_DASH
),
new
Sample
(
"WV: Secure video path required"
,
"0894c7c8719b28a0"
,
"http://www.youtube.com/api/manifest/dash/id/0894c7c8719b28a0/source/youtube?"
+
"as=fmp4_audio_cenc,fmp4_sd_hd_cenc&sparams=ip,ipbits,expire,source,id,as&ip=0.0.0.0"
+
"&ipbits=0&expire=19000000000&signature=A41D835C7387885A4A820628F57E481E00095931."
+
"9D50DBEEB5E37344647EE11BDA129A7FCDE8B7B9&key=ik0"
,
DemoUtil
.
TYPE_DASH
),
+
"9D50DBEEB5E37344647EE11BDA129A7FCDE8B7B9&key=ik0"
,
PlayerActivity
.
TYPE_DASH
),
new
Sample
(
"WV: HDCP + secure video path required"
,
"efd045b1eb61888a"
,
"http://www.youtube.com/api/manifest/dash/id/efd045b1eb61888a/source/youtube"
+
"as=fmp4_audio_cenc,fmp4_sd_hd_cenc&sparams=ip,ipbits,expire,source,id,as&ip=0.0.0.0"
+
"&ipbits=0&expire=19000000000&signature=A97C9032C9D0C74F1643DB17C178873887C229E4."
+
"0A657BF6F23C8BC1538F276137383478330B76DE&key=ik0"
,
DemoUtil
.
TYPE_DASH
),
+
"0A657BF6F23C8BC1538F276137383478330B76DE&key=ik0"
,
PlayerActivity
.
TYPE_DASH
),
new
Sample
(
"WV: 30s license duration (fails at ~30s)"
,
"f9a34cab7b05881a"
,
"http://www.youtube.com/api/manifest/dash/id/f9a34cab7b05881a/source/youtube?"
+
"as=fmp4_audio_cenc,fmp4_sd_hd_cenc&sparams=ip,ipbits,expire,source,id,as&ip=0.0.0.0"
+
"&ipbits=0&expire=19000000000&signature=80648A12A7D5FC1FA02B52B4250E4EB74CF0C5FD."
+
"66A261130CA137AA5C541EA9CED2DBF240829EE6&key=ik0"
,
DemoUtil
.
TYPE_DASH
),
+
"66A261130CA137AA5C541EA9CED2DBF240829EE6&key=ik0"
,
PlayerActivity
.
TYPE_DASH
),
};
public
static
final
Sample
[]
HLS
=
new
Sample
[]
{
new
Sample
(
"Apple master playlist"
,
"https://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/"
+
"bipbop_4x3_variant.m3u8"
,
DemoUtil
.
TYPE_HLS
),
+
"bipbop_4x3_variant.m3u8"
,
PlayerActivity
.
TYPE_HLS
),
new
Sample
(
"Apple master playlist advanced"
,
"https://devimages.apple.com.edgekey.net/streaming/examples/bipbop_16x9/"
+
"bipbop_16x9_variant.m3u8"
,
DemoUtil
.
TYPE_HLS
),
+
"bipbop_16x9_variant.m3u8"
,
PlayerActivity
.
TYPE_HLS
),
new
Sample
(
"Apple TS media playlist"
,
"https://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/gear1/"
+
"prog_index.m3u8"
,
DemoUtil
.
TYPE_HLS
),
+
"prog_index.m3u8"
,
PlayerActivity
.
TYPE_HLS
),
new
Sample
(
"Apple AAC media playlist"
,
"https://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/gear0/"
+
"prog_index.m3u8"
,
DemoUtil
.
TYPE_HLS
),
+
"prog_index.m3u8"
,
PlayerActivity
.
TYPE_HLS
),
new
Sample
(
"Apple ID3 metadata"
,
"http://devimages.apple.com/samplecode/adDemo/ad.m3u8"
,
DemoUtil
.
TYPE_HLS
),
PlayerActivity
.
TYPE_HLS
),
};
public
static
final
Sample
[]
MISC
=
new
Sample
[]
{
new
Sample
(
"Dizzy"
,
"http://html5demos.com/assets/dizzy.mp4"
,
DemoUtil
.
TYPE_MP4
),
PlayerActivity
.
TYPE_MP4
),
new
Sample
(
"Apple AAC 10s"
,
"https://devimages.apple.com.edgekey.net/"
+
"streaming/examples/bipbop_4x3/gear0/fileSequence0.aac"
,
DemoUtil
.
TYPE_AAC
),
PlayerActivity
.
TYPE_AAC
),
new
Sample
(
"Apple TS 10s"
,
"https://devimages.apple.com.edgekey.net/streaming/examples/"
+
"bipbop_4x3/gear1/fileSequence0.ts"
,
DemoUtil
.
TYPE_TS
),
PlayerActivity
.
TYPE_TS
),
new
Sample
(
"Big Buck Bunny (MP4 Video)"
,
"http://redirector.c.youtube.com/videoplayback?id=604ed5ce52eda7ee&itag=22&source=youtube&"
+
"sparams=ip,ipbits,expire,source,id&ip=0.0.0.0&ipbits=0&expire=19000000000&signature="
+
"513F28C7FDCBEC60A66C86C9A393556C99DC47FB.04C88036EEE12565A1ED864A875A58F15D8B5300"
+
"&key=ik0"
,
DemoUtil
.
TYPE_MP4
),
PlayerActivity
.
TYPE_MP4
),
new
Sample
(
"Google Play (MP3 Audio)"
,
"http://storage.googleapis.com/exoplayer-test-media-0/play.mp3"
,
DemoUtil
.
TYPE_MP3
),
PlayerActivity
.
TYPE_MP3
),
new
Sample
(
"Google Glass (WebM Video with Vorbis Audio)"
,
"http://demos.webmproject.org/exoplayer/glass_vp9_vorbis.webm"
,
DemoUtil
.
TYPE_WEBM
),
PlayerActivity
.
TYPE_WEBM
),
};
private
Samples
()
{}
...
...
demo/src/main/java/com/google/android/exoplayer/demo/SmoothStreamingTestMediaDrmCallback.java
View file @
a85a1696
...
...
@@ -17,6 +17,7 @@ package com.google.android.exoplayer.demo;
import
com.google.android.exoplayer.drm.MediaDrmCallback
;
import
com.google.android.exoplayer.drm.StreamingDrmSessionManager
;
import
com.google.android.exoplayer.util.Util
;
import
android.annotation.TargetApi
;
import
android.media.MediaDrm.KeyRequest
;
...
...
@@ -48,7 +49,7 @@ public class SmoothStreamingTestMediaDrmCallback implements MediaDrmCallback {
@Override
public
byte
[]
executeProvisionRequest
(
UUID
uuid
,
ProvisionRequest
request
)
throws
IOException
{
String
url
=
request
.
getDefaultUrl
()
+
"&signedRequest="
+
new
String
(
request
.
getData
());
return
Demo
Util
.
executePost
(
url
,
null
,
null
);
return
Util
.
executePost
(
url
,
null
,
null
);
}
@Override
...
...
@@ -57,7 +58,7 @@ public class SmoothStreamingTestMediaDrmCallback implements MediaDrmCallback {
if
(
TextUtils
.
isEmpty
(
url
))
{
url
=
PLAYREADY_TEST_DEFAULT_URI
;
}
return
Demo
Util
.
executePost
(
url
,
request
.
getData
(),
KEY_REQUEST_PROPERTIES
);
return
Util
.
executePost
(
url
,
request
.
getData
(),
KEY_REQUEST_PROPERTIES
);
}
}
demo/src/main/java/com/google/android/exoplayer/demo/WidevineTestMediaDrmCallback.java
View file @
a85a1696
...
...
@@ -16,6 +16,7 @@
package
com
.
google
.
android
.
exoplayer
.
demo
;
import
com.google.android.exoplayer.drm.MediaDrmCallback
;
import
com.google.android.exoplayer.util.Util
;
import
android.annotation.TargetApi
;
import
android.media.MediaDrm.KeyRequest
;
...
...
@@ -43,7 +44,7 @@ public class WidevineTestMediaDrmCallback implements MediaDrmCallback {
@Override
public
byte
[]
executeProvisionRequest
(
UUID
uuid
,
ProvisionRequest
request
)
throws
IOException
{
String
url
=
request
.
getDefaultUrl
()
+
"&signedRequest="
+
new
String
(
request
.
getData
());
return
Demo
Util
.
executePost
(
url
,
null
,
null
);
return
Util
.
executePost
(
url
,
null
,
null
);
}
@Override
...
...
@@ -52,7 +53,7 @@ public class WidevineTestMediaDrmCallback implements MediaDrmCallback {
if
(
TextUtils
.
isEmpty
(
url
))
{
url
=
defaultUri
;
}
return
Demo
Util
.
executePost
(
url
,
request
.
getData
(),
null
);
return
Util
.
executePost
(
url
,
request
.
getData
(),
null
);
}
}
demo/src/main/java/com/google/android/exoplayer/demo/player/DashRendererBuilder.java
View file @
a85a1696
...
...
@@ -42,9 +42,9 @@ import com.google.android.exoplayer.dash.mpd.UtcTimingElementResolver;
import
com.google.android.exoplayer.dash.mpd.UtcTimingElementResolver.UtcTimingCallback
;
import
com.google.android.exoplayer.demo.player.DemoPlayer.RendererBuilder
;
import
com.google.android.exoplayer.demo.player.DemoPlayer.RendererBuilderCallback
;
import
com.google.android.exoplayer.drm.DrmSessionManager
;
import
com.google.android.exoplayer.drm.MediaDrmCallback
;
import
com.google.android.exoplayer.drm.StreamingDrmSessionManager
;
import
com.google.android.exoplayer.drm.UnsupportedDrmException
;
import
com.google.android.exoplayer.text.TextTrackRenderer
;
import
com.google.android.exoplayer.text.ttml.TtmlParser
;
import
com.google.android.exoplayer.text.webvtt.WebvttParser
;
...
...
@@ -57,14 +57,10 @@ import com.google.android.exoplayer.util.ManifestFetcher;
import
com.google.android.exoplayer.util.ManifestFetcher.ManifestCallback
;
import
com.google.android.exoplayer.util.Util
;
import
android.annotation.TargetApi
;
import
android.content.Context
;
import
android.media.MediaCodec
;
import
android.media.UnsupportedSchemeException
;
import
android.os.Handler
;
import
android.util.Log
;
import
android.util.Pair
;
import
android.widget.TextView
;
import
java.io.IOException
;
import
java.util.ArrayList
;
...
...
@@ -104,7 +100,6 @@ public class DashRendererBuilder implements RendererBuilder,
private
final
String
userAgent
;
private
final
String
url
;
private
final
MediaDrmCallback
drmCallback
;
private
final
TextView
debugTextView
;
private
final
AudioCapabilities
audioCapabilities
;
private
DemoPlayer
player
;
...
...
@@ -116,12 +111,11 @@ public class DashRendererBuilder implements RendererBuilder,
private
long
elapsedRealtimeOffset
;
public
DashRendererBuilder
(
Context
context
,
String
userAgent
,
String
url
,
MediaDrmCallback
drmCallback
,
TextView
debugTextView
,
AudioCapabilities
audioCapabilities
)
{
MediaDrmCallback
drmCallback
,
AudioCapabilities
audioCapabilities
)
{
this
.
context
=
context
;
this
.
userAgent
=
userAgent
;
this
.
url
=
url
;
this
.
drmCallback
=
drmCallback
;
this
.
debugTextView
=
debugTextView
;
this
.
audioCapabilities
=
audioCapabilities
;
}
...
...
@@ -192,20 +186,18 @@ public class DashRendererBuilder implements RendererBuilder,
// Check drm support if necessary.
boolean
filterHdContent
=
false
;
DrmSessionManager
drmSessionManager
=
null
;
Streaming
DrmSessionManager
drmSessionManager
=
null
;
if
(
hasContentProtection
)
{
if
(
Util
.
SDK_INT
<
18
)
{
callback
.
onRenderersError
(
new
UnsupportedDrmException
(
UnsupportedDrmException
.
REASON_
NO_DRM
));
new
UnsupportedDrmException
(
UnsupportedDrmException
.
REASON_
UNSUPPORTED_SCHEME
));
return
;
}
try
{
Pair
<
DrmSessionManager
,
Boolean
>
drmSessionManagerData
=
V18Compat
.
getDrmSessionManagerData
(
player
,
drmCallback
);
drmSessionManager
=
drmSessionManagerData
.
first
;
// HD streams require L1 security.
drmSessionManager
=
StreamingDrmSessionManager
.
newWidevineInstance
(
player
.
getPlaybackLooper
(),
drmCallback
,
null
,
player
.
getMainHandler
(),
player
);
filterHdContent
=
videoAdaptationSet
!=
null
&&
videoAdaptationSet
.
hasContentProtection
()
&&
!
drmSessionManagerData
.
second
;
&&
getWidevineSecurityLevel
(
drmSessionManager
)
!=
SECURITY_LEVEL_1
;
}
catch
(
UnsupportedDrmException
e
)
{
callback
.
onRenderersError
(
e
);
return
;
...
...
@@ -226,10 +218,8 @@ public class DashRendererBuilder implements RendererBuilder,
// Build the video renderer.
final
MediaCodecVideoTrackRenderer
videoRenderer
;
final
TrackRenderer
debugRenderer
;
if
(
videoRepresentationIndices
==
null
||
videoRepresentationIndices
.
length
==
0
)
{
videoRenderer
=
null
;
debugRenderer
=
null
;
}
else
{
DataSource
videoDataSource
=
new
DefaultUriDataSource
(
context
,
bandwidthMeter
,
userAgent
);
ChunkSource
videoChunkSource
=
new
DashChunkSource
(
manifestFetcher
,
...
...
@@ -240,8 +230,6 @@ public class DashRendererBuilder implements RendererBuilder,
DemoPlayer
.
TYPE_VIDEO
);
videoRenderer
=
new
MediaCodecVideoTrackRenderer
(
videoSampleSource
,
drmSessionManager
,
true
,
MediaCodec
.
VIDEO_SCALING_MODE_SCALE_TO_FIT
,
5000
,
null
,
mainHandler
,
player
,
50
);
debugRenderer
=
debugTextView
!=
null
?
new
DebugTrackRenderer
(
debugTextView
,
player
,
videoRenderer
,
bandwidthMeter
)
:
null
;
}
// Build the audio chunk sources.
...
...
@@ -353,34 +341,13 @@ public class DashRendererBuilder implements RendererBuilder,
renderers
[
DemoPlayer
.
TYPE_VIDEO
]
=
videoRenderer
;
renderers
[
DemoPlayer
.
TYPE_AUDIO
]
=
audioRenderer
;
renderers
[
DemoPlayer
.
TYPE_TEXT
]
=
textRenderer
;
renderers
[
DemoPlayer
.
TYPE_DEBUG
]
=
debugRenderer
;
callback
.
onRenderers
(
trackNames
,
multiTrackChunkSources
,
renderers
);
callback
.
onRenderers
(
trackNames
,
multiTrackChunkSources
,
renderers
,
bandwidthMeter
);
}
@TargetApi
(
18
)
private
static
class
V18Compat
{
public
static
Pair
<
DrmSessionManager
,
Boolean
>
getDrmSessionManagerData
(
DemoPlayer
player
,
MediaDrmCallback
drmCallback
)
throws
UnsupportedDrmException
{
try
{
StreamingDrmSessionManager
streamingDrmSessionManager
=
StreamingDrmSessionManager
.
newWidevineInstance
(
player
.
getPlaybackLooper
(),
drmCallback
,
null
,
player
.
getMainHandler
(),
player
);
return
Pair
.
create
((
DrmSessionManager
)
streamingDrmSessionManager
,
getWidevineSecurityLevel
(
streamingDrmSessionManager
)
==
SECURITY_LEVEL_1
);
}
catch
(
UnsupportedSchemeException
e
)
{
throw
new
UnsupportedDrmException
(
UnsupportedDrmException
.
REASON_UNSUPPORTED_SCHEME
);
}
catch
(
Exception
e
)
{
throw
new
UnsupportedDrmException
(
UnsupportedDrmException
.
REASON_UNKNOWN
,
e
);
}
}
private
static
int
getWidevineSecurityLevel
(
StreamingDrmSessionManager
sessionManager
)
{
String
securityLevelProperty
=
sessionManager
.
getPropertyString
(
"securityLevel"
);
return
securityLevelProperty
.
equals
(
"L1"
)
?
SECURITY_LEVEL_1
:
securityLevelProperty
.
equals
(
"L3"
)
?
SECURITY_LEVEL_3
:
SECURITY_LEVEL_UNKNOWN
;
}
private
static
int
getWidevineSecurityLevel
(
StreamingDrmSessionManager
sessionManager
)
{
String
securityLevelProperty
=
sessionManager
.
getPropertyString
(
"securityLevel"
);
return
securityLevelProperty
.
equals
(
"L1"
)
?
SECURITY_LEVEL_1
:
securityLevelProperty
.
equals
(
"L3"
)
?
SECURITY_LEVEL_3
:
SECURITY_LEVEL_UNKNOWN
;
}
}
demo/src/main/java/com/google/android/exoplayer/demo/player/DebugTrackRenderer.java
deleted
100644 → 0
View file @
b806109c
/*
* 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
.
demo
.
player
;
import
com.google.android.exoplayer.ExoPlaybackException
;
import
com.google.android.exoplayer.MediaCodecTrackRenderer
;
import
com.google.android.exoplayer.TrackRenderer
;
import
com.google.android.exoplayer.chunk.Format
;
import
com.google.android.exoplayer.upstream.BandwidthMeter
;
import
android.widget.TextView
;
/**
* A {@link TrackRenderer} that periodically updates debugging information displayed by a
* {@link TextView}.
*/
/* package */
class
DebugTrackRenderer
extends
TrackRenderer
implements
Runnable
{
private
final
TextView
textView
;
private
final
DemoPlayer
player
;
private
final
MediaCodecTrackRenderer
renderer
;
private
final
BandwidthMeter
bandwidthMeter
;
private
volatile
boolean
pendingFailure
;
private
volatile
long
currentPositionUs
;
public
DebugTrackRenderer
(
TextView
textView
,
DemoPlayer
player
,
MediaCodecTrackRenderer
renderer
)
{
this
(
textView
,
player
,
renderer
,
null
);
}
public
DebugTrackRenderer
(
TextView
textView
,
DemoPlayer
player
,
MediaCodecTrackRenderer
renderer
,
BandwidthMeter
bandwidthMeter
)
{
this
.
textView
=
textView
;
this
.
player
=
player
;
this
.
renderer
=
renderer
;
this
.
bandwidthMeter
=
bandwidthMeter
;
}
public
void
injectFailure
()
{
pendingFailure
=
true
;
}
@Override
protected
boolean
isEnded
()
{
return
true
;
}
@Override
protected
boolean
isReady
()
{
return
true
;
}
@Override
protected
int
doPrepare
(
long
positionUs
)
throws
ExoPlaybackException
{
maybeFail
();
return
STATE_PREPARED
;
}
@Override
protected
void
doSomeWork
(
long
positionUs
,
long
elapsedRealtimeUs
)
throws
ExoPlaybackException
{
maybeFail
();
if
(
positionUs
<
currentPositionUs
||
positionUs
>
currentPositionUs
+
1000000
)
{
currentPositionUs
=
positionUs
;
textView
.
post
(
this
);
}
}
@Override
public
void
run
()
{
textView
.
setText
(
getRenderString
());
}
private
String
getRenderString
()
{
return
getTimeString
()
+
" "
+
getQualityString
()
+
" "
+
getBandwidthString
()
+
" "
+
renderer
.
codecCounters
.
getDebugString
();
}
private
String
getTimeString
()
{
return
"ms("
+
(
currentPositionUs
/
1000
)
+
")"
;
}
private
String
getQualityString
()
{
Format
format
=
player
.
getVideoFormat
();
return
format
==
null
?
"id:? br:? h:?"
:
"id:"
+
format
.
id
+
" br:"
+
format
.
bitrate
+
" h:"
+
format
.
height
;
}
private
String
getBandwidthString
()
{
if
(
bandwidthMeter
==
null
||
bandwidthMeter
.
getBitrateEstimate
()
==
BandwidthMeter
.
NO_ESTIMATE
)
{
return
"bw:?"
;
}
else
{
return
"bw:"
+
(
bandwidthMeter
.
getBitrateEstimate
()
/
1000
);
}
}
@Override
protected
long
getCurrentPositionUs
()
{
return
currentPositionUs
;
}
@Override
protected
long
getDurationUs
()
{
return
TrackRenderer
.
MATCH_LONGEST_US
;
}
@Override
protected
long
getBufferedPositionUs
()
{
return
TrackRenderer
.
END_OF_TRACK_US
;
}
@Override
protected
void
seekTo
(
long
timeUs
)
{
currentPositionUs
=
timeUs
;
}
private
void
maybeFail
()
throws
ExoPlaybackException
{
if
(
pendingFailure
)
{
pendingFailure
=
false
;
throw
new
ExoPlaybackException
(
"fail() was called on DebugTrackRenderer"
);
}
}
}
demo/src/main/java/com/google/android/exoplayer/demo/player/DemoPlayer.java
View file @
a85a1696
...
...
@@ -15,10 +15,12 @@
*/
package
com
.
google
.
android
.
exoplayer
.
demo
.
player
;
import
com.google.android.exoplayer.CodecCounters
;
import
com.google.android.exoplayer.DummyTrackRenderer
;
import
com.google.android.exoplayer.ExoPlaybackException
;
import
com.google.android.exoplayer.ExoPlayer
;
import
com.google.android.exoplayer.MediaCodecAudioTrackRenderer
;
import
com.google.android.exoplayer.MediaCodecTrackRenderer
;
import
com.google.android.exoplayer.MediaCodecTrackRenderer.DecoderInitializationException
;
import
com.google.android.exoplayer.MediaCodecVideoTrackRenderer
;
import
com.google.android.exoplayer.TimeRange
;
...
...
@@ -29,10 +31,12 @@ import com.google.android.exoplayer.chunk.Format;
import
com.google.android.exoplayer.chunk.MultiTrackChunkSource
;
import
com.google.android.exoplayer.drm.StreamingDrmSessionManager
;
import
com.google.android.exoplayer.hls.HlsSampleSource
;
import
com.google.android.exoplayer.metadata.MetadataTrackRenderer
;
import
com.google.android.exoplayer.metadata.MetadataTrackRenderer
.MetadataRenderer
;
import
com.google.android.exoplayer.text.Cue
;
import
com.google.android.exoplayer.text.TextRenderer
;
import
com.google.android.exoplayer.upstream.BandwidthMeter
;
import
com.google.android.exoplayer.upstream.DefaultBandwidthMeter
;
import
com.google.android.exoplayer.util.DebugTextViewHelper
;
import
com.google.android.exoplayer.util.PlayerControl
;
import
android.media.MediaCodec.CryptoException
;
...
...
@@ -54,7 +58,8 @@ import java.util.concurrent.CopyOnWriteArrayList;
public
class
DemoPlayer
implements
ExoPlayer
.
Listener
,
ChunkSampleSource
.
EventListener
,
HlsSampleSource
.
EventListener
,
DefaultBandwidthMeter
.
EventListener
,
MediaCodecVideoTrackRenderer
.
EventListener
,
MediaCodecAudioTrackRenderer
.
EventListener
,
StreamingDrmSessionManager
.
EventListener
,
TextRenderer
{
StreamingDrmSessionManager
.
EventListener
,
TextRenderer
,
MetadataRenderer
<
Map
<
String
,
Object
>>,
DebugTextViewHelper
.
Provider
{
/**
* Builds renderers for the player.
...
...
@@ -84,9 +89,10 @@ public class DemoPlayer implements ExoPlayer.Listener, ChunkSampleSource.EventLi
* multiple tracks. An individual element may be null if it does not have multiple tracks.
* @param renderers Renderers indexed by {@link DemoPlayer} TYPE_* constants. An individual
* element may be null if there do not exist tracks of the corresponding type.
* @param bandwidthMeter Provides an estimate of the currently available bandwidth. May be null.
*/
void
onRenderers
(
String
[][]
trackNames
,
MultiTrackChunkSource
[]
multiTrackSources
,
TrackRenderer
[]
renderers
);
TrackRenderer
[]
renderers
,
BandwidthMeter
bandwidthMeter
);
/**
* Invoked if a {@link RendererBuilder} encounters an error.
*
...
...
@@ -163,12 +169,11 @@ public class DemoPlayer implements ExoPlayer.Listener, ChunkSampleSource.EventLi
public
static
final
int
DISABLED_TRACK
=
-
1
;
public
static
final
int
PRIMARY_TRACK
=
0
;
public
static
final
int
RENDERER_COUNT
=
5
;
public
static
final
int
RENDERER_COUNT
=
4
;
public
static
final
int
TYPE_VIDEO
=
0
;
public
static
final
int
TYPE_AUDIO
=
1
;
public
static
final
int
TYPE_TEXT
=
2
;
public
static
final
int
TYPE_TIMED_METADATA
=
3
;
public
static
final
int
TYPE_DEBUG
=
4
;
public
static
final
int
TYPE_METADATA
=
3
;
private
static
final
int
RENDERER_BUILDING_STATE_IDLE
=
1
;
private
static
final
int
RENDERER_BUILDING_STATE_BUILDING
=
2
;
...
...
@@ -187,9 +192,11 @@ public class DemoPlayer implements ExoPlayer.Listener, ChunkSampleSource.EventLi
private
Surface
surface
;
private
InternalRendererBuilderCallback
builderCallback
;
private
TrackRenderer
videoRenderer
;
private
CodecCounters
codecCounters
;
private
Format
videoFormat
;
private
int
videoTrackToRestore
;
private
BandwidthMeter
bandwidthMeter
;
private
MultiTrackChunkSource
[]
multiTrackSources
;
private
String
[][]
trackNames
;
private
int
[]
selectedTracks
;
...
...
@@ -275,10 +282,6 @@ public class DemoPlayer implements ExoPlayer.Listener, ChunkSampleSource.EventLi
}
}
public
Format
getVideoFormat
()
{
return
videoFormat
;
}
public
void
setBackgrounded
(
boolean
backgrounded
)
{
if
(
this
.
backgrounded
==
backgrounded
)
{
return
;
...
...
@@ -310,7 +313,8 @@ public class DemoPlayer implements ExoPlayer.Listener, ChunkSampleSource.EventLi
}
/* package */
void
onRenderers
(
String
[][]
trackNames
,
MultiTrackChunkSource
[]
multiTrackSources
,
TrackRenderer
[]
renderers
)
{
MultiTrackChunkSource
[]
multiTrackSources
,
TrackRenderer
[]
renderers
,
BandwidthMeter
bandwidthMeter
)
{
builderCallback
=
null
;
// Normalize the results.
if
(
trackNames
==
null
)
{
...
...
@@ -333,7 +337,12 @@ public class DemoPlayer implements ExoPlayer.Listener, ChunkSampleSource.EventLi
// Complete preparation.
this
.
trackNames
=
trackNames
;
this
.
videoRenderer
=
renderers
[
TYPE_VIDEO
];
this
.
codecCounters
=
videoRenderer
instanceof
MediaCodecTrackRenderer
?
((
MediaCodecTrackRenderer
)
videoRenderer
).
codecCounters
:
renderers
[
TYPE_AUDIO
]
instanceof
MediaCodecTrackRenderer
?
((
MediaCodecTrackRenderer
)
renderers
[
TYPE_AUDIO
]).
codecCounters
:
null
;
this
.
multiTrackSources
=
multiTrackSources
;
this
.
bandwidthMeter
=
bandwidthMeter
;
pushSurface
(
false
);
pushTrackSelection
(
TYPE_VIDEO
,
true
);
pushTrackSelection
(
TYPE_AUDIO
,
true
);
...
...
@@ -387,6 +396,22 @@ public class DemoPlayer implements ExoPlayer.Listener, ChunkSampleSource.EventLi
return
playerState
;
}
@Override
public
Format
getFormat
()
{
return
videoFormat
;
}
@Override
public
BandwidthMeter
getBandwidthMeter
()
{
return
bandwidthMeter
;
}
@Override
public
CodecCounters
getCodecCounters
()
{
return
codecCounters
;
}
@Override
public
long
getCurrentPosition
()
{
return
player
.
getCurrentPosition
();
}
...
...
@@ -494,9 +519,7 @@ public class DemoPlayer implements ExoPlayer.Listener, ChunkSampleSource.EventLi
}
@Override
public
void
onDecoderInitialized
(
String
decoderName
,
long
elapsedRealtimeMs
,
public
void
onDecoderInitialized
(
String
decoderName
,
long
elapsedRealtimeMs
,
long
initializationDurationMs
)
{
if
(
infoListener
!=
null
)
{
infoListener
.
onDecoderInitialized
(
decoderName
,
elapsedRealtimeMs
,
initializationDurationMs
);
...
...
@@ -512,19 +535,16 @@ public class DemoPlayer implements ExoPlayer.Listener, ChunkSampleSource.EventLi
@Override
public
void
onCues
(
List
<
Cue
>
cues
)
{
processCues
(
cues
);
if
(
captionListener
!=
null
&&
selectedTracks
[
TYPE_TEXT
]
!=
DISABLED_TRACK
)
{
captionListener
.
onCues
(
cues
);
}
}
/* package */
MetadataTrackRenderer
.
MetadataRenderer
<
Map
<
String
,
Object
>>
getId3MetadataRenderer
()
{
return
new
MetadataTrackRenderer
.
MetadataRenderer
<
Map
<
String
,
Object
>>()
{
@Override
public
void
onMetadata
(
Map
<
String
,
Object
>
metadata
)
{
if
(
id3MetadataListener
!=
null
)
{
id3MetadataListener
.
onId3Metadata
(
metadata
);
}
}
};
@Override
public
void
onMetadata
(
Map
<
String
,
Object
>
metadata
)
{
if
(
id3MetadataListener
!=
null
&&
selectedTracks
[
TYPE_METADATA
]
!=
DISABLED_TRACK
)
{
id3MetadataListener
.
onId3Metadata
(
metadata
);
}
}
@Override
...
...
@@ -612,13 +632,6 @@ public class DemoPlayer implements ExoPlayer.Listener, ChunkSampleSource.EventLi
}
}
/* package */
void
processCues
(
List
<
Cue
>
cues
)
{
if
(
captionListener
==
null
||
selectedTracks
[
TYPE_TEXT
]
==
DISABLED_TRACK
)
{
return
;
}
captionListener
.
onCues
(
cues
);
}
private
class
InternalRendererBuilderCallback
implements
RendererBuilderCallback
{
private
boolean
canceled
;
...
...
@@ -629,9 +642,9 @@ public class DemoPlayer implements ExoPlayer.Listener, ChunkSampleSource.EventLi
@Override
public
void
onRenderers
(
String
[][]
trackNames
,
MultiTrackChunkSource
[]
multiTrackSources
,
TrackRenderer
[]
renderers
)
{
TrackRenderer
[]
renderers
,
BandwidthMeter
bandwidthMeter
)
{
if
(!
canceled
)
{
DemoPlayer
.
this
.
onRenderers
(
trackNames
,
multiTrackSources
,
renderers
);
DemoPlayer
.
this
.
onRenderers
(
trackNames
,
multiTrackSources
,
renderers
,
bandwidthMeter
);
}
}
...
...
demo/src/main/java/com/google/android/exoplayer/demo/player/ExtractorRendererBuilder.java
View file @
a85a1696
...
...
@@ -29,7 +29,6 @@ import com.google.android.exoplayer.upstream.DefaultUriDataSource;
import
android.content.Context
;
import
android.media.MediaCodec
;
import
android.net.Uri
;
import
android.widget.TextView
;
/**
* A {@link RendererBuilder} for streams that can be read using an {@link Extractor}.
...
...
@@ -41,15 +40,12 @@ public class ExtractorRendererBuilder implements RendererBuilder {
private
final
Context
context
;
private
final
String
userAgent
;
private
final
Uri
uri
;
private
final
TextView
debugTextView
;
private
final
Extractor
extractor
;
public
ExtractorRendererBuilder
(
Context
context
,
String
userAgent
,
Uri
uri
,
TextView
debugTextView
,
Extractor
extractor
)
{
public
ExtractorRendererBuilder
(
Context
context
,
String
userAgent
,
Uri
uri
,
Extractor
extractor
)
{
this
.
context
=
context
;
this
.
userAgent
=
userAgent
;
this
.
uri
=
uri
;
this
.
debugTextView
=
debugTextView
;
this
.
extractor
=
extractor
;
}
...
...
@@ -67,16 +63,11 @@ public class ExtractorRendererBuilder implements RendererBuilder {
MediaCodecAudioTrackRenderer
audioRenderer
=
new
MediaCodecAudioTrackRenderer
(
sampleSource
,
null
,
true
,
player
.
getMainHandler
(),
player
);
// Build the debug renderer.
TrackRenderer
debugRenderer
=
debugTextView
!=
null
?
new
DebugTrackRenderer
(
debugTextView
,
player
,
videoRenderer
,
bandwidthMeter
)
:
null
;
// Invoke the callback.
TrackRenderer
[]
renderers
=
new
TrackRenderer
[
DemoPlayer
.
RENDERER_COUNT
];
renderers
[
DemoPlayer
.
TYPE_VIDEO
]
=
videoRenderer
;
renderers
[
DemoPlayer
.
TYPE_AUDIO
]
=
audioRenderer
;
renderers
[
DemoPlayer
.
TYPE_DEBUG
]
=
debugRenderer
;
callback
.
onRenderers
(
null
,
null
,
renderers
);
callback
.
onRenderers
(
null
,
null
,
renderers
,
bandwidthMeter
);
}
}
demo/src/main/java/com/google/android/exoplayer/demo/player/HlsRendererBuilder.java
View file @
a85a1696
...
...
@@ -43,7 +43,6 @@ import com.google.android.exoplayer.util.ManifestFetcher.ManifestCallback;
import
android.content.Context
;
import
android.media.MediaCodec
;
import
android.os.Handler
;
import
android.widget.TextView
;
import
java.io.IOException
;
import
java.util.Map
;
...
...
@@ -59,18 +58,16 @@ public class HlsRendererBuilder implements RendererBuilder, ManifestCallback<Hls
private
final
Context
context
;
private
final
String
userAgent
;
private
final
String
url
;
private
final
TextView
debugTextView
;
private
final
AudioCapabilities
audioCapabilities
;
private
DemoPlayer
player
;
private
RendererBuilderCallback
callback
;
public
HlsRendererBuilder
(
Context
context
,
String
userAgent
,
String
url
,
TextView
debugTextView
,
public
HlsRendererBuilder
(
Context
context
,
String
userAgent
,
String
url
,
AudioCapabilities
audioCapabilities
)
{
this
.
context
=
context
;
this
.
userAgent
=
userAgent
;
this
.
url
=
url
;
this
.
debugTextView
=
debugTextView
;
this
.
audioCapabilities
=
audioCapabilities
;
}
...
...
@@ -117,23 +114,17 @@ public class HlsRendererBuilder implements RendererBuilder, ManifestCallback<Hls
MediaCodecAudioTrackRenderer
audioRenderer
=
new
MediaCodecAudioTrackRenderer
(
sampleSource
);
MetadataTrackRenderer
<
Map
<
String
,
Object
>>
id3Renderer
=
new
MetadataTrackRenderer
<>(
sampleSource
,
new
Id3Parser
(),
player
.
getId3MetadataRenderer
(),
mainHandler
.
getLooper
());
new
MetadataTrackRenderer
<>(
sampleSource
,
new
Id3Parser
(),
player
,
mainHandler
.
getLooper
());
Eia608TrackRenderer
closedCaptionRenderer
=
new
Eia608TrackRenderer
(
sampleSource
,
player
,
mainHandler
.
getLooper
());
// Build the debug renderer.
TrackRenderer
debugRenderer
=
debugTextView
!=
null
?
new
DebugTrackRenderer
(
debugTextView
,
player
,
videoRenderer
,
bandwidthMeter
)
:
null
;
TrackRenderer
[]
renderers
=
new
TrackRenderer
[
DemoPlayer
.
RENDERER_COUNT
];
renderers
[
DemoPlayer
.
TYPE_VIDEO
]
=
videoRenderer
;
renderers
[
DemoPlayer
.
TYPE_AUDIO
]
=
audioRenderer
;
renderers
[
DemoPlayer
.
TYPE_
TIMED_
METADATA
]
=
id3Renderer
;
renderers
[
DemoPlayer
.
TYPE_METADATA
]
=
id3Renderer
;
renderers
[
DemoPlayer
.
TYPE_TEXT
]
=
closedCaptionRenderer
;
renderers
[
DemoPlayer
.
TYPE_DEBUG
]
=
debugRenderer
;
callback
.
onRenderers
(
null
,
null
,
renderers
);
callback
.
onRenderers
(
null
,
null
,
renderers
,
bandwidthMeter
);
}
}
demo/src/main/java/com/google/android/exoplayer/demo/player/SmoothStreamingRendererBuilder.java
View file @
a85a1696
...
...
@@ -32,6 +32,7 @@ import com.google.android.exoplayer.demo.player.DemoPlayer.RendererBuilderCallba
import
com.google.android.exoplayer.drm.DrmSessionManager
;
import
com.google.android.exoplayer.drm.MediaDrmCallback
;
import
com.google.android.exoplayer.drm.StreamingDrmSessionManager
;
import
com.google.android.exoplayer.drm.UnsupportedDrmException
;
import
com.google.android.exoplayer.smoothstreaming.SmoothStreamingChunkSource
;
import
com.google.android.exoplayer.smoothstreaming.SmoothStreamingManifest
;
import
com.google.android.exoplayer.smoothstreaming.SmoothStreamingManifest.StreamElement
;
...
...
@@ -46,16 +47,12 @@ import com.google.android.exoplayer.upstream.DefaultUriDataSource;
import
com.google.android.exoplayer.util.ManifestFetcher
;
import
com.google.android.exoplayer.util.Util
;
import
android.annotation.TargetApi
;
import
android.content.Context
;
import
android.media.MediaCodec
;
import
android.media.UnsupportedSchemeException
;
import
android.os.Handler
;
import
android.widget.TextView
;
import
java.io.IOException
;
import
java.util.Arrays
;
import
java.util.UUID
;
/**
* A {@link RendererBuilder} for SmoothStreaming.
...
...
@@ -73,19 +70,17 @@ public class SmoothStreamingRendererBuilder implements RendererBuilder,
private
final
String
userAgent
;
private
final
String
url
;
private
final
MediaDrmCallback
drmCallback
;
private
final
TextView
debugTextView
;
private
DemoPlayer
player
;
private
RendererBuilderCallback
callback
;
private
ManifestFetcher
<
SmoothStreamingManifest
>
manifestFetcher
;
public
SmoothStreamingRendererBuilder
(
Context
context
,
String
userAgent
,
String
url
,
MediaDrmCallback
drmCallback
,
TextView
debugTextView
)
{
MediaDrmCallback
drmCallback
)
{
this
.
context
=
context
;
this
.
userAgent
=
userAgent
;
this
.
url
=
url
;
this
.
drmCallback
=
drmCallback
;
this
.
debugTextView
=
debugTextView
;
}
@Override
...
...
@@ -118,12 +113,12 @@ public class SmoothStreamingRendererBuilder implements RendererBuilder,
if
(
manifest
.
protectionElement
!=
null
)
{
if
(
Util
.
SDK_INT
<
18
)
{
callback
.
onRenderersError
(
new
UnsupportedDrmException
(
UnsupportedDrmException
.
REASON_
NO_DRM
));
new
UnsupportedDrmException
(
UnsupportedDrmException
.
REASON_
UNSUPPORTED_SCHEME
));
return
;
}
try
{
drmSessionManager
=
V18Compat
.
getDrmSessionManager
(
manifest
.
protectionElement
.
uuid
,
player
,
drmCallback
);
drmSessionManager
=
new
StreamingDrmSessionManager
(
manifest
.
protectionElement
.
uuid
,
player
.
getPlaybackLooper
(),
drmCallback
,
null
,
player
.
getMainHandler
(),
player
);
}
catch
(
UnsupportedDrmException
e
)
{
callback
.
onRenderersError
(
e
);
return
;
...
...
@@ -159,10 +154,8 @@ public class SmoothStreamingRendererBuilder implements RendererBuilder,
// Build the video renderer.
final
MediaCodecVideoTrackRenderer
videoRenderer
;
final
TrackRenderer
debugRenderer
;
if
(
videoTrackIndices
==
null
||
videoTrackIndices
.
length
==
0
)
{
videoRenderer
=
null
;
debugRenderer
=
null
;
}
else
{
DataSource
videoDataSource
=
new
DefaultUriDataSource
(
context
,
bandwidthMeter
,
userAgent
);
ChunkSource
videoChunkSource
=
new
SmoothStreamingChunkSource
(
manifestFetcher
,
...
...
@@ -173,8 +166,6 @@ public class SmoothStreamingRendererBuilder implements RendererBuilder,
DemoPlayer
.
TYPE_VIDEO
);
videoRenderer
=
new
MediaCodecVideoTrackRenderer
(
videoSampleSource
,
drmSessionManager
,
true
,
MediaCodec
.
VIDEO_SCALING_MODE_SCALE_TO_FIT
,
5000
,
null
,
mainHandler
,
player
,
50
);
debugRenderer
=
debugTextView
!=
null
?
new
DebugTrackRenderer
(
debugTextView
,
player
,
videoRenderer
,
bandwidthMeter
)
:
null
;
}
// Build the audio renderer.
...
...
@@ -252,25 +243,7 @@ public class SmoothStreamingRendererBuilder implements RendererBuilder,
renderers
[
DemoPlayer
.
TYPE_VIDEO
]
=
videoRenderer
;
renderers
[
DemoPlayer
.
TYPE_AUDIO
]
=
audioRenderer
;
renderers
[
DemoPlayer
.
TYPE_TEXT
]
=
textRenderer
;
renderers
[
DemoPlayer
.
TYPE_DEBUG
]
=
debugRenderer
;
callback
.
onRenderers
(
trackNames
,
multiTrackChunkSources
,
renderers
);
}
@TargetApi
(
18
)
private
static
class
V18Compat
{
public
static
DrmSessionManager
getDrmSessionManager
(
UUID
uuid
,
DemoPlayer
player
,
MediaDrmCallback
drmCallback
)
throws
UnsupportedDrmException
{
try
{
return
new
StreamingDrmSessionManager
(
uuid
,
player
.
getPlaybackLooper
(),
drmCallback
,
null
,
player
.
getMainHandler
(),
player
);
}
catch
(
UnsupportedSchemeException
e
)
{
throw
new
UnsupportedDrmException
(
UnsupportedDrmException
.
REASON_UNSUPPORTED_SCHEME
);
}
catch
(
Exception
e
)
{
throw
new
UnsupportedDrmException
(
UnsupportedDrmException
.
REASON_UNKNOWN
,
e
);
}
}
callback
.
onRenderers
(
trackNames
,
multiTrackChunkSources
,
renderers
,
bandwidthMeter
);
}
}
library/src/main/java/com/google/android/exoplayer/drm/StreamingDrmSessionManager.java
View file @
a85a1696
...
...
@@ -110,11 +110,11 @@ public class StreamingDrmSessionManager implements DrmSessionManager {
* @param eventHandler A handler to use when delivering events to {@code eventListener}. May be
* null if delivery of events is not required.
* @param eventListener A listener of events. May be null if delivery of events is not required.
* @throws Unsupported
Scheme
Exception If the specified DRM scheme is not supported.
* @throws Unsupported
Drm
Exception If the specified DRM scheme is not supported.
*/
public
static
StreamingDrmSessionManager
newWidevineInstance
(
Looper
playbackLooper
,
MediaDrmCallback
callback
,
HashMap
<
String
,
String
>
optionalKeyRequestParameters
,
Handler
eventHandler
,
EventListener
eventListener
)
throws
Unsupported
Scheme
Exception
{
Handler
eventHandler
,
EventListener
eventListener
)
throws
Unsupported
Drm
Exception
{
return
new
StreamingDrmSessionManager
(
WIDEVINE_UUID
,
playbackLooper
,
callback
,
optionalKeyRequestParameters
,
eventHandler
,
eventListener
);
}
...
...
@@ -132,11 +132,11 @@ public class StreamingDrmSessionManager implements DrmSessionManager {
* @param eventHandler A handler to use when delivering events to {@code eventListener}. May be
* null if delivery of events is not required.
* @param eventListener A listener of events. May be null if delivery of events is not required.
* @throws Unsupported
Scheme
Exception If the specified DRM scheme is not supported.
* @throws Unsupported
Drm
Exception If the specified DRM scheme is not supported.
*/
public
static
StreamingDrmSessionManager
newPlayReadyInstance
(
Looper
playbackLooper
,
MediaDrmCallback
callback
,
String
customData
,
Handler
eventHandler
,
EventListener
eventListener
)
throws
Unsupported
Scheme
Exception
{
EventListener
eventListener
)
throws
Unsupported
Drm
Exception
{
HashMap
<
String
,
String
>
optionalKeyRequestParameters
;
if
(!
TextUtils
.
isEmpty
(
customData
))
{
optionalKeyRequestParameters
=
new
HashMap
<>();
...
...
@@ -158,17 +158,23 @@ public class StreamingDrmSessionManager implements DrmSessionManager {
* @param eventHandler A handler to use when delivering events to {@code eventListener}. May be
* null if delivery of events is not required.
* @param eventListener A listener of events. May be null if delivery of events is not required.
* @throws Unsupported
Scheme
Exception If the specified DRM scheme is not supported.
* @throws Unsupported
Drm
Exception If the specified DRM scheme is not supported.
*/
public
StreamingDrmSessionManager
(
UUID
uuid
,
Looper
playbackLooper
,
MediaDrmCallback
callback
,
HashMap
<
String
,
String
>
optionalKeyRequestParameters
,
Handler
eventHandler
,
EventListener
eventListener
)
throws
Unsupported
Scheme
Exception
{
EventListener
eventListener
)
throws
Unsupported
Drm
Exception
{
this
.
uuid
=
uuid
;
this
.
callback
=
callback
;
this
.
optionalKeyRequestParameters
=
optionalKeyRequestParameters
;
this
.
eventHandler
=
eventHandler
;
this
.
eventListener
=
eventListener
;
mediaDrm
=
new
MediaDrm
(
uuid
);
try
{
mediaDrm
=
new
MediaDrm
(
uuid
);
}
catch
(
UnsupportedSchemeException
e
)
{
throw
new
UnsupportedDrmException
(
UnsupportedDrmException
.
REASON_UNSUPPORTED_SCHEME
,
e
);
}
catch
(
Exception
e
)
{
throw
new
UnsupportedDrmException
(
UnsupportedDrmException
.
REASON_INSTANTIATION_ERROR
,
e
);
}
mediaDrm
.
setOnEventListener
(
new
MediaDrmEventListener
());
mediaDrmHandler
=
new
MediaDrmHandler
(
playbackLooper
);
postResponseHandler
=
new
PostResponseHandler
(
playbackLooper
);
...
...
@@ -176,12 +182,12 @@ public class StreamingDrmSessionManager implements DrmSessionManager {
}
@Override
public
int
getState
()
{
public
final
int
getState
()
{
return
state
;
}
@Override
public
MediaCrypto
getMediaCrypto
()
{
public
final
MediaCrypto
getMediaCrypto
()
{
if
(
state
!=
STATE_OPENED
&&
state
!=
STATE_OPENED_WITH_KEYS
)
{
throw
new
IllegalStateException
();
}
...
...
@@ -197,7 +203,7 @@ public class StreamingDrmSessionManager implements DrmSessionManager {
}
@Override
public
Exception
getError
()
{
public
final
Exception
getError
()
{
return
state
==
STATE_ERROR
?
lastException
:
null
;
}
...
...
@@ -250,7 +256,7 @@ public class StreamingDrmSessionManager implements DrmSessionManager {
}
@Override
public
void
open
(
DrmInitData
drmInitData
)
{
public
final
void
open
(
DrmInitData
drmInitData
)
{
if
(++
openCount
!=
1
)
{
return
;
}
...
...
@@ -272,7 +278,7 @@ public class StreamingDrmSessionManager implements DrmSessionManager {
}
@Override
public
void
close
()
{
public
final
void
close
()
{
if
(--
openCount
!=
0
)
{
return
;
}
...
...
demo/src/main/java/com/google/android/exoplayer/demo/player
/UnsupportedDrmException.java
→
library/src/main/java/com/google/android/exoplayer/drm
/UnsupportedDrmException.java
View file @
a85a1696
...
...
@@ -13,16 +13,22 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com
.
google
.
android
.
exoplayer
.
d
emo
.
player
;
package
com
.
google
.
android
.
exoplayer
.
d
rm
;
/**
*
Exception thrown when the required level of DRM
is not supported.
*
Thrown when the requested DRM scheme
is not supported.
*/
public
final
class
UnsupportedDrmException
extends
Exception
{
public
static
final
int
REASON_NO_DRM
=
0
;
/**
* The requested DRM scheme is unsupported by the device.
*/
public
static
final
int
REASON_UNSUPPORTED_SCHEME
=
1
;
public
static
final
int
REASON_UNKNOWN
=
2
;
/**
* There device advertises support for the requested DRM scheme, but there was an error
* instantiating it. The cause can be retrieved using {@link #getCause()}.
*/
public
static
final
int
REASON_INSTANTIATION_ERROR
=
2
;
public
final
int
reason
;
...
...
library/src/main/java/com/google/android/exoplayer/util/DebugTextViewHelper.java
0 → 100644
View file @
a85a1696
/*
* 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
.
util
;
import
com.google.android.exoplayer.CodecCounters
;
import
com.google.android.exoplayer.chunk.Format
;
import
com.google.android.exoplayer.upstream.BandwidthMeter
;
import
android.widget.TextView
;
/**
* A helper class for periodically updating debug information displayed by a {@link TextView}.
*/
public
final
class
DebugTextViewHelper
implements
Runnable
{
/**
* Provides debug information about an ongoing playback.
*/
public
interface
Provider
{
/**
* Returns the current playback position, in milliseconds.
*/
long
getCurrentPosition
();
/**
* Returns a format whose information should be displayed, or null.
*/
Format
getFormat
();
/**
* Returns a {@link BandwidthMeter} whose estimate should be displayed, or null.
*/
BandwidthMeter
getBandwidthMeter
();
/**
* Returns a {@link CodecCounters} whose information should be displayed, or null.
*/
CodecCounters
getCodecCounters
();
}
private
static
final
int
REFRESH_INTERVAL_MS
=
1000
;
private
final
TextView
textView
;
private
final
Provider
debuggable
;
/**
* @param debuggable The {@link Provider} from which debug information should be obtained.
* @param textView The {@link TextView} that should be updated to display the information.
*/
public
DebugTextViewHelper
(
Provider
debuggable
,
TextView
textView
)
{
this
.
debuggable
=
debuggable
;
this
.
textView
=
textView
;
}
/**
* Starts periodic updates of the {@link TextView}.
* <p>
* Should be called from the application's main thread.
*/
public
void
start
()
{
stop
();
run
();
}
/**
* Stops periodic updates of the {@link TextView}.
* <p>
* Should be called from the application's main thread.
*/
public
void
stop
()
{
textView
.
removeCallbacks
(
this
);
}
@Override
public
void
run
()
{
textView
.
setText
(
getRenderString
());
textView
.
postDelayed
(
this
,
REFRESH_INTERVAL_MS
);
}
private
String
getRenderString
()
{
return
getTimeString
()
+
" "
+
getQualityString
()
+
" "
+
getBandwidthString
()
+
" "
+
getVideoCodecCountersString
();
}
private
String
getTimeString
()
{
return
"ms("
+
debuggable
.
getCurrentPosition
()
+
")"
;
}
private
String
getQualityString
()
{
Format
format
=
debuggable
.
getFormat
();
return
format
==
null
?
"id:? br:? h:?"
:
"id:"
+
format
.
id
+
" br:"
+
format
.
bitrate
+
" h:"
+
format
.
height
;
}
private
String
getBandwidthString
()
{
BandwidthMeter
bandwidthMeter
=
debuggable
.
getBandwidthMeter
();
if
(
bandwidthMeter
==
null
||
bandwidthMeter
.
getBitrateEstimate
()
==
BandwidthMeter
.
NO_ESTIMATE
)
{
return
"bw:?"
;
}
else
{
return
"bw:"
+
(
bandwidthMeter
.
getBitrateEstimate
()
/
1000
);
}
}
private
String
getVideoCodecCountersString
()
{
CodecCounters
codecCounters
=
debuggable
.
getCodecCounters
();
return
codecCounters
==
null
?
""
:
codecCounters
.
getDebugString
();
}
}
library/src/main/java/com/google/android/exoplayer/util/Util.java
View file @
a85a1696
...
...
@@ -26,6 +26,7 @@ import android.content.pm.PackageManager.NameNotFoundException;
import
android.os.Build
;
import
android.text.TextUtils
;
import
java.io.ByteArrayOutputStream
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
...
...
@@ -40,6 +41,7 @@ import java.util.Collections;
import
java.util.GregorianCalendar
;
import
java.util.List
;
import
java.util.Locale
;
import
java.util.Map
;
import
java.util.TimeZone
;
import
java.util.concurrent.ExecutorService
;
import
java.util.concurrent.Executors
;
...
...
@@ -583,4 +585,56 @@ public final class Util {
+
") "
+
"ExoPlayerLib/"
+
ExoPlayerLibraryInfo
.
VERSION
;
}
/**
* Executes a post request using {@link HttpURLConnection}.
*
* @param url The request URL.
* @param data The request body, or null.
* @param requestProperties Request properties, or null.
* @return The response body.
* @throws IOException If an error occurred making the request.
*/
// TODO: Remove this and use HttpDataSource once DataSpec supports inclusion of a POST body.
public
static
byte
[]
executePost
(
String
url
,
byte
[]
data
,
Map
<
String
,
String
>
requestProperties
)
throws
IOException
{
HttpURLConnection
urlConnection
=
null
;
try
{
urlConnection
=
(
HttpURLConnection
)
new
URL
(
url
).
openConnection
();
urlConnection
.
setRequestMethod
(
"POST"
);
urlConnection
.
setDoOutput
(
data
!=
null
);
urlConnection
.
setDoInput
(
true
);
if
(
requestProperties
!=
null
)
{
for
(
Map
.
Entry
<
String
,
String
>
requestProperty
:
requestProperties
.
entrySet
())
{
urlConnection
.
setRequestProperty
(
requestProperty
.
getKey
(),
requestProperty
.
getValue
());
}
}
// Write the request body, if there is one.
if
(
data
!=
null
)
{
OutputStream
out
=
urlConnection
.
getOutputStream
();
try
{
out
.
write
(
data
);
}
finally
{
out
.
close
();
}
}
// Read and return the response body.
InputStream
inputStream
=
urlConnection
.
getInputStream
();
try
{
ByteArrayOutputStream
byteArrayOutputStream
=
new
ByteArrayOutputStream
();
byte
scratch
[]
=
new
byte
[
1024
];
int
bytesRead
;
while
((
bytesRead
=
inputStream
.
read
(
scratch
))
!=
-
1
)
{
byteArrayOutputStream
.
write
(
scratch
,
0
,
bytesRead
);
}
return
byteArrayOutputStream
.
toByteArray
();
}
finally
{
inputStream
.
close
();
}
}
finally
{
if
(
urlConnection
!=
null
)
{
urlConnection
.
disconnect
();
}
}
}
}
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