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
410fcdeb
authored
Nov 26, 2014
by
Oliver Woodman
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Merge HLS playlist parsers, make a single parser identify the
playlist type (master or media). Issue: #155
parent
f9f3b82d
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
230 additions
and
198 deletions
demo/src/main/java/com/google/android/exoplayer/demo/DemoUtil.java
demo/src/main/java/com/google/android/exoplayer/demo/Samples.java
demo/src/main/java/com/google/android/exoplayer/demo/full/FullPlayerActivity.java
demo/src/main/java/com/google/android/exoplayer/demo/full/player/HlsRendererBuilder.java
demo/src/main/java/com/google/android/exoplayer/demo/simple/HlsRendererBuilder.java
demo/src/main/java/com/google/android/exoplayer/demo/simple/SimplePlayerActivity.java
library/src/main/java/com/google/android/exoplayer/hls/HlsChunkSource.java
library/src/main/java/com/google/android/exoplayer/hls/HlsMasterPlaylist.java
library/src/main/java/com/google/android/exoplayer/hls/HlsMasterPlaylistParser.java
library/src/main/java/com/google/android/exoplayer/hls/HlsMediaPlaylist.java
library/src/main/java/com/google/android/exoplayer/hls/HlsPlaylist.java
library/src/main/java/com/google/android/exoplayer/hls/HlsMediaPlaylistParser.java → library/src/main/java/com/google/android/exoplayer/hls/HlsPlaylistParser.java
demo/src/main/java/com/google/android/exoplayer/demo/DemoUtil.java
View file @
410fcdeb
...
@@ -50,8 +50,9 @@ public class DemoUtil {
...
@@ -50,8 +50,9 @@ public class DemoUtil {
public
static
final
int
TYPE_DASH_VOD
=
0
;
public
static
final
int
TYPE_DASH_VOD
=
0
;
public
static
final
int
TYPE_SS
=
1
;
public
static
final
int
TYPE_SS
=
1
;
public
static
final
int
TYPE_OTHER
=
2
;
public
static
final
int
TYPE_OTHER
=
2
;
public
static
final
int
TYPE_HLS_MASTER
=
3
;
public
static
final
int
TYPE_DASH_LIVE
=
3
;
public
static
final
int
TYPE_HLS_MEDIA
=
4
;
public
static
final
int
TYPE_DASH_LIVE_DVR
=
4
;
public
static
final
int
TYPE_HLS
=
5
;
public
static
final
boolean
EXPOSE_EXPERIMENTAL_FEATURES
=
false
;
public
static
final
boolean
EXPOSE_EXPERIMENTAL_FEATURES
=
false
;
...
...
demo/src/main/java/com/google/android/exoplayer/demo/Samples.java
View file @
410fcdeb
...
@@ -59,7 +59,7 @@ package com.google.android.exoplayer.demo;
...
@@ -59,7 +59,7 @@ package com.google.android.exoplayer.demo;
DemoUtil
.
TYPE_SS
,
false
,
false
),
DemoUtil
.
TYPE_SS
,
false
,
false
),
new
Sample
(
"Apple master playlist (HLS)"
,
"uid:hls:applemaster"
,
new
Sample
(
"Apple master playlist (HLS)"
,
"uid:hls:applemaster"
,
"https://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/"
"https://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/"
+
"bipbop_4x3_variant.m3u8"
,
DemoUtil
.
TYPE_HLS
_MASTER
,
false
,
false
),
+
"bipbop_4x3_variant.m3u8"
,
DemoUtil
.
TYPE_HLS
,
false
,
false
),
new
Sample
(
"Dizzy (Misc)"
,
"uid:misc:dizzy"
,
new
Sample
(
"Dizzy (Misc)"
,
"uid:misc:dizzy"
,
"http://html5demos.com/assets/dizzy.mp4"
,
DemoUtil
.
TYPE_OTHER
,
false
,
false
),
"http://html5demos.com/assets/dizzy.mp4"
,
DemoUtil
.
TYPE_OTHER
,
false
,
false
),
};
};
...
@@ -137,13 +137,13 @@ package com.google.android.exoplayer.demo;
...
@@ -137,13 +137,13 @@ package com.google.android.exoplayer.demo;
public
static
final
Sample
[]
HLS
=
new
Sample
[]
{
public
static
final
Sample
[]
HLS
=
new
Sample
[]
{
new
Sample
(
"Apple master playlist"
,
"uid:hls:applemaster"
,
new
Sample
(
"Apple master playlist"
,
"uid:hls:applemaster"
,
"https://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/"
"https://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/"
+
"bipbop_4x3_variant.m3u8"
,
DemoUtil
.
TYPE_HLS
_MASTER
,
false
,
true
),
+
"bipbop_4x3_variant.m3u8"
,
DemoUtil
.
TYPE_HLS
,
false
,
true
),
new
Sample
(
"Apple master playlist advanced"
,
"uid:hls:applemasteradvanced"
,
new
Sample
(
"Apple master playlist advanced"
,
"uid:hls:applemasteradvanced"
,
"https://devimages.apple.com.edgekey.net/streaming/examples/bipbop_16x9/"
"https://devimages.apple.com.edgekey.net/streaming/examples/bipbop_16x9/"
+
"bipbop_16x9_variant.m3u8"
,
DemoUtil
.
TYPE_HLS
_MASTER
,
false
,
true
),
+
"bipbop_16x9_variant.m3u8"
,
DemoUtil
.
TYPE_HLS
,
false
,
true
),
new
Sample
(
"Apple single media playlist"
,
"uid:hls:applesinglemedia"
,
new
Sample
(
"Apple single media playlist"
,
"uid:hls:applesinglemedia"
,
"https://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/gear1/"
"https://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/gear1/"
+
"prog_index.m3u8"
,
DemoUtil
.
TYPE_HLS
_MEDIA
,
false
,
true
),
+
"prog_index.m3u8"
,
DemoUtil
.
TYPE_HLS
,
false
,
true
),
};
};
public
static
final
Sample
[]
MISC
=
new
Sample
[]
{
public
static
final
Sample
[]
MISC
=
new
Sample
[]
{
...
...
demo/src/main/java/com/google/android/exoplayer/demo/full/FullPlayerActivity.java
View file @
410fcdeb
...
@@ -185,9 +185,8 @@ public class FullPlayerActivity extends Activity implements SurfaceHolder.Callba
...
@@ -185,9 +185,8 @@ public class FullPlayerActivity extends Activity implements SurfaceHolder.Callba
case
DemoUtil
.
TYPE_DASH_VOD
:
case
DemoUtil
.
TYPE_DASH_VOD
:
return
new
DashVodRendererBuilder
(
userAgent
,
contentUri
.
toString
(),
contentId
,
return
new
DashVodRendererBuilder
(
userAgent
,
contentUri
.
toString
(),
contentId
,
new
WidevineTestMediaDrmCallback
(
contentId
),
debugTextView
);
new
WidevineTestMediaDrmCallback
(
contentId
),
debugTextView
);
case
DemoUtil
.
TYPE_HLS_MASTER
:
case
DemoUtil
.
TYPE_HLS
:
case
DemoUtil
.
TYPE_HLS_MEDIA
:
return
new
HlsRendererBuilder
(
userAgent
,
contentUri
.
toString
(),
contentId
);
return
new
HlsRendererBuilder
(
userAgent
,
contentUri
.
toString
(),
contentId
,
contentType
);
default
:
default
:
return
new
DefaultRendererBuilder
(
this
,
contentUri
,
debugTextView
);
return
new
DefaultRendererBuilder
(
this
,
contentUri
,
debugTextView
);
}
}
...
@@ -429,7 +428,7 @@ public class FullPlayerActivity extends Activity implements SurfaceHolder.Callba
...
@@ -429,7 +428,7 @@ public class FullPlayerActivity extends Activity implements SurfaceHolder.Callba
}
}
}
}
//DemoPlayer.ClosedCaptioListener implementation
//
DemoPlayer.ClosedCaptioListener implementation
@Override
@Override
public
void
onClosedCaption
(
List
<
ClosedCaption
>
closedCaptions
)
{
public
void
onClosedCaption
(
List
<
ClosedCaption
>
closedCaptions
)
{
...
...
demo/src/main/java/com/google/android/exoplayer/demo/full/player/HlsRendererBuilder.java
View file @
410fcdeb
...
@@ -19,14 +19,12 @@ import com.google.android.exoplayer.MediaCodecAudioTrackRenderer;
...
@@ -19,14 +19,12 @@ import com.google.android.exoplayer.MediaCodecAudioTrackRenderer;
import
com.google.android.exoplayer.MediaCodecUtil
;
import
com.google.android.exoplayer.MediaCodecUtil
;
import
com.google.android.exoplayer.MediaCodecVideoTrackRenderer
;
import
com.google.android.exoplayer.MediaCodecVideoTrackRenderer
;
import
com.google.android.exoplayer.TrackRenderer
;
import
com.google.android.exoplayer.TrackRenderer
;
import
com.google.android.exoplayer.demo.DemoUtil
;
import
com.google.android.exoplayer.demo.full.player.DemoPlayer.RendererBuilder
;
import
com.google.android.exoplayer.demo.full.player.DemoPlayer.RendererBuilder
;
import
com.google.android.exoplayer.demo.full.player.DemoPlayer.RendererBuilderCallback
;
import
com.google.android.exoplayer.demo.full.player.DemoPlayer.RendererBuilderCallback
;
import
com.google.android.exoplayer.hls.HlsChunkSource
;
import
com.google.android.exoplayer.hls.HlsChunkSource
;
import
com.google.android.exoplayer.hls.Hls
Master
Playlist
;
import
com.google.android.exoplayer.hls.HlsPlaylist
;
import
com.google.android.exoplayer.hls.Hls
Master
PlaylistParser
;
import
com.google.android.exoplayer.hls.HlsPlaylistParser
;
import
com.google.android.exoplayer.hls.HlsSampleSource
;
import
com.google.android.exoplayer.hls.HlsSampleSource
;
import
com.google.android.exoplayer.hls.Variant
;
import
com.google.android.exoplayer.metadata.ClosedCaption
;
import
com.google.android.exoplayer.metadata.ClosedCaption
;
import
com.google.android.exoplayer.metadata.Eia608Parser
;
import
com.google.android.exoplayer.metadata.Eia608Parser
;
import
com.google.android.exoplayer.metadata.Id3Parser
;
import
com.google.android.exoplayer.metadata.Id3Parser
;
...
@@ -39,48 +37,37 @@ import com.google.android.exoplayer.util.ManifestFetcher.ManifestCallback;
...
@@ -39,48 +37,37 @@ import com.google.android.exoplayer.util.ManifestFetcher.ManifestCallback;
import
com.google.android.exoplayer.util.MimeTypes
;
import
com.google.android.exoplayer.util.MimeTypes
;
import
android.media.MediaCodec
;
import
android.media.MediaCodec
;
import
android.net.Uri
;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Map
;
/**
/**
* A {@link RendererBuilder} for HLS.
* A {@link RendererBuilder} for HLS.
*/
*/
public
class
HlsRendererBuilder
implements
RendererBuilder
,
ManifestCallback
<
Hls
Master
Playlist
>
{
public
class
HlsRendererBuilder
implements
RendererBuilder
,
ManifestCallback
<
HlsPlaylist
>
{
private
final
String
userAgent
;
private
final
String
userAgent
;
private
final
String
url
;
private
final
String
url
;
private
final
String
contentId
;
private
final
String
contentId
;
private
final
int
contentType
;
private
DemoPlayer
player
;
private
DemoPlayer
player
;
private
RendererBuilderCallback
callback
;
private
RendererBuilderCallback
callback
;
public
HlsRendererBuilder
(
String
userAgent
,
String
url
,
String
contentId
,
int
contentType
)
{
public
HlsRendererBuilder
(
String
userAgent
,
String
url
,
String
contentId
)
{
this
.
userAgent
=
userAgent
;
this
.
userAgent
=
userAgent
;
this
.
url
=
url
;
this
.
url
=
url
;
this
.
contentId
=
contentId
;
this
.
contentId
=
contentId
;
this
.
contentType
=
contentType
;
}
}
@Override
@Override
public
void
buildRenderers
(
DemoPlayer
player
,
RendererBuilderCallback
callback
)
{
public
void
buildRenderers
(
DemoPlayer
player
,
RendererBuilderCallback
callback
)
{
this
.
player
=
player
;
this
.
player
=
player
;
this
.
callback
=
callback
;
this
.
callback
=
callback
;
switch
(
contentType
)
{
HlsPlaylistParser
parser
=
new
HlsPlaylistParser
();
case
DemoUtil
.
TYPE_HLS_MASTER
:
ManifestFetcher
<
HlsPlaylist
>
playlistFetcher
=
HlsMasterPlaylistParser
parser
=
new
HlsMasterPlaylistParser
();
new
ManifestFetcher
<
HlsPlaylist
>(
parser
,
contentId
,
url
,
userAgent
);
ManifestFetcher
<
HlsMasterPlaylist
>
mediaPlaylistFetcher
=
playlistFetcher
.
singleLoad
(
player
.
getMainHandler
().
getLooper
(),
this
);
new
ManifestFetcher
<
HlsMasterPlaylist
>(
parser
,
contentId
,
url
,
userAgent
);
mediaPlaylistFetcher
.
singleLoad
(
player
.
getMainHandler
().
getLooper
(),
this
);
break
;
case
DemoUtil
.
TYPE_HLS_MEDIA
:
onManifest
(
contentId
,
newSimpleMasterPlaylist
(
url
));
break
;
}
}
}
@Override
@Override
...
@@ -89,11 +76,11 @@ public class HlsRendererBuilder implements RendererBuilder, ManifestCallback<Hls
...
@@ -89,11 +76,11 @@ public class HlsRendererBuilder implements RendererBuilder, ManifestCallback<Hls
}
}
@Override
@Override
public
void
onManifest
(
String
contentId
,
Hls
Master
Playlist
manifest
)
{
public
void
onManifest
(
String
contentId
,
HlsPlaylist
manifest
)
{
DefaultBandwidthMeter
bandwidthMeter
=
new
DefaultBandwidthMeter
();
DefaultBandwidthMeter
bandwidthMeter
=
new
DefaultBandwidthMeter
();
DataSource
dataSource
=
new
UriDataSource
(
userAgent
,
bandwidthMeter
);
DataSource
dataSource
=
new
UriDataSource
(
userAgent
,
bandwidthMeter
);
HlsChunkSource
chunkSource
=
new
HlsChunkSource
(
dataSource
,
manifest
,
bandwidthMeter
,
null
,
HlsChunkSource
chunkSource
=
new
HlsChunkSource
(
dataSource
,
url
,
manifest
,
bandwidthMeter
,
null
,
MediaCodecUtil
.
getDecoderInfo
(
MimeTypes
.
VIDEO_H264
,
false
).
adaptive
);
MediaCodecUtil
.
getDecoderInfo
(
MimeTypes
.
VIDEO_H264
,
false
).
adaptive
);
HlsSampleSource
sampleSource
=
new
HlsSampleSource
(
chunkSource
,
true
,
3
);
HlsSampleSource
sampleSource
=
new
HlsSampleSource
(
chunkSource
,
true
,
3
);
MediaCodecVideoTrackRenderer
videoRenderer
=
new
MediaCodecVideoTrackRenderer
(
sampleSource
,
MediaCodecVideoTrackRenderer
videoRenderer
=
new
MediaCodecVideoTrackRenderer
(
sampleSource
,
...
@@ -116,9 +103,4 @@ public class HlsRendererBuilder implements RendererBuilder, ManifestCallback<Hls
...
@@ -116,9 +103,4 @@ public class HlsRendererBuilder implements RendererBuilder, ManifestCallback<Hls
callback
.
onRenderers
(
null
,
null
,
renderers
);
callback
.
onRenderers
(
null
,
null
,
renderers
);
}
}
private
HlsMasterPlaylist
newSimpleMasterPlaylist
(
String
mediaPlaylistUrl
)
{
return
new
HlsMasterPlaylist
(
Uri
.
parse
(
""
),
Collections
.
singletonList
(
new
Variant
(
0
,
mediaPlaylistUrl
,
0
,
null
,
-
1
,
-
1
)));
}
}
}
demo/src/main/java/com/google/android/exoplayer/demo/simple/HlsRendererBuilder.java
View file @
410fcdeb
...
@@ -19,15 +19,13 @@ import com.google.android.exoplayer.MediaCodecAudioTrackRenderer;
...
@@ -19,15 +19,13 @@ import com.google.android.exoplayer.MediaCodecAudioTrackRenderer;
import
com.google.android.exoplayer.MediaCodecUtil
;
import
com.google.android.exoplayer.MediaCodecUtil
;
import
com.google.android.exoplayer.MediaCodecVideoTrackRenderer
;
import
com.google.android.exoplayer.MediaCodecVideoTrackRenderer
;
import
com.google.android.exoplayer.TrackRenderer
;
import
com.google.android.exoplayer.TrackRenderer
;
import
com.google.android.exoplayer.demo.DemoUtil
;
import
com.google.android.exoplayer.demo.full.player.DemoPlayer
;
import
com.google.android.exoplayer.demo.full.player.DemoPlayer
;
import
com.google.android.exoplayer.demo.simple.SimplePlayerActivity.RendererBuilder
;
import
com.google.android.exoplayer.demo.simple.SimplePlayerActivity.RendererBuilder
;
import
com.google.android.exoplayer.demo.simple.SimplePlayerActivity.RendererBuilderCallback
;
import
com.google.android.exoplayer.demo.simple.SimplePlayerActivity.RendererBuilderCallback
;
import
com.google.android.exoplayer.hls.HlsChunkSource
;
import
com.google.android.exoplayer.hls.HlsChunkSource
;
import
com.google.android.exoplayer.hls.Hls
Master
Playlist
;
import
com.google.android.exoplayer.hls.HlsPlaylist
;
import
com.google.android.exoplayer.hls.Hls
Master
PlaylistParser
;
import
com.google.android.exoplayer.hls.HlsPlaylistParser
;
import
com.google.android.exoplayer.hls.HlsSampleSource
;
import
com.google.android.exoplayer.hls.HlsSampleSource
;
import
com.google.android.exoplayer.hls.Variant
;
import
com.google.android.exoplayer.upstream.DataSource
;
import
com.google.android.exoplayer.upstream.DataSource
;
import
com.google.android.exoplayer.upstream.DefaultBandwidthMeter
;
import
com.google.android.exoplayer.upstream.DefaultBandwidthMeter
;
import
com.google.android.exoplayer.upstream.UriDataSource
;
import
com.google.android.exoplayer.upstream.UriDataSource
;
...
@@ -36,48 +34,37 @@ import com.google.android.exoplayer.util.ManifestFetcher.ManifestCallback;
...
@@ -36,48 +34,37 @@ import com.google.android.exoplayer.util.ManifestFetcher.ManifestCallback;
import
com.google.android.exoplayer.util.MimeTypes
;
import
com.google.android.exoplayer.util.MimeTypes
;
import
android.media.MediaCodec
;
import
android.media.MediaCodec
;
import
android.net.Uri
;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.util.Collections
;
/**
/**
* A {@link RendererBuilder} for HLS.
* A {@link RendererBuilder} for HLS.
*/
*/
/* package */
class
HlsRendererBuilder
implements
RendererBuilder
,
/* package */
class
HlsRendererBuilder
implements
RendererBuilder
,
ManifestCallback
<
Hls
Master
Playlist
>
{
ManifestCallback
<
HlsPlaylist
>
{
private
final
SimplePlayerActivity
playerActivity
;
private
final
SimplePlayerActivity
playerActivity
;
private
final
String
userAgent
;
private
final
String
userAgent
;
private
final
String
url
;
private
final
String
url
;
private
final
String
contentId
;
private
final
String
contentId
;
private
final
int
playlistType
;
private
RendererBuilderCallback
callback
;
private
RendererBuilderCallback
callback
;
public
HlsRendererBuilder
(
SimplePlayerActivity
playerActivity
,
String
userAgent
,
String
url
,
public
HlsRendererBuilder
(
SimplePlayerActivity
playerActivity
,
String
userAgent
,
String
url
,
String
contentId
,
int
playlistType
)
{
String
contentId
)
{
this
.
playerActivity
=
playerActivity
;
this
.
playerActivity
=
playerActivity
;
this
.
userAgent
=
userAgent
;
this
.
userAgent
=
userAgent
;
this
.
url
=
url
;
this
.
url
=
url
;
this
.
contentId
=
contentId
;
this
.
contentId
=
contentId
;
this
.
playlistType
=
playlistType
;
}
}
@Override
@Override
public
void
buildRenderers
(
RendererBuilderCallback
callback
)
{
public
void
buildRenderers
(
RendererBuilderCallback
callback
)
{
this
.
callback
=
callback
;
this
.
callback
=
callback
;
switch
(
playlistType
)
{
HlsPlaylistParser
parser
=
new
HlsPlaylistParser
();
case
DemoUtil
.
TYPE_HLS_MASTER
:
ManifestFetcher
<
HlsPlaylist
>
playlistFetcher
=
HlsMasterPlaylistParser
parser
=
new
HlsMasterPlaylistParser
();
new
ManifestFetcher
<
HlsPlaylist
>(
parser
,
contentId
,
url
,
userAgent
);
ManifestFetcher
<
HlsMasterPlaylist
>
mediaPlaylistFetcher
=
playlistFetcher
.
singleLoad
(
playerActivity
.
getMainLooper
(),
this
);
new
ManifestFetcher
<
HlsMasterPlaylist
>(
parser
,
contentId
,
url
,
userAgent
);
mediaPlaylistFetcher
.
singleLoad
(
playerActivity
.
getMainLooper
(),
this
);
break
;
case
DemoUtil
.
TYPE_HLS_MEDIA
:
onManifest
(
contentId
,
newSimpleMasterPlaylist
(
url
));
break
;
}
}
}
@Override
@Override
...
@@ -86,10 +73,11 @@ import java.util.Collections;
...
@@ -86,10 +73,11 @@ import java.util.Collections;
}
}
@Override
@Override
public
void
onManifest
(
String
contentId
,
Hls
Master
Playlist
manifest
)
{
public
void
onManifest
(
String
contentId
,
HlsPlaylist
manifest
)
{
DefaultBandwidthMeter
bandwidthMeter
=
new
DefaultBandwidthMeter
();
DefaultBandwidthMeter
bandwidthMeter
=
new
DefaultBandwidthMeter
();
DataSource
dataSource
=
new
UriDataSource
(
userAgent
,
bandwidthMeter
);
DataSource
dataSource
=
new
UriDataSource
(
userAgent
,
bandwidthMeter
);
HlsChunkSource
chunkSource
=
new
HlsChunkSource
(
dataSource
,
manifest
,
bandwidthMeter
,
null
,
HlsChunkSource
chunkSource
=
new
HlsChunkSource
(
dataSource
,
url
,
manifest
,
bandwidthMeter
,
null
,
MediaCodecUtil
.
getDecoderInfo
(
MimeTypes
.
VIDEO_H264
,
false
).
adaptive
);
MediaCodecUtil
.
getDecoderInfo
(
MimeTypes
.
VIDEO_H264
,
false
).
adaptive
);
HlsSampleSource
sampleSource
=
new
HlsSampleSource
(
chunkSource
,
true
,
2
);
HlsSampleSource
sampleSource
=
new
HlsSampleSource
(
chunkSource
,
true
,
2
);
MediaCodecVideoTrackRenderer
videoRenderer
=
new
MediaCodecVideoTrackRenderer
(
sampleSource
,
MediaCodecVideoTrackRenderer
videoRenderer
=
new
MediaCodecVideoTrackRenderer
(
sampleSource
,
...
@@ -103,9 +91,4 @@ import java.util.Collections;
...
@@ -103,9 +91,4 @@ import java.util.Collections;
callback
.
onRenderers
(
videoRenderer
,
audioRenderer
);
callback
.
onRenderers
(
videoRenderer
,
audioRenderer
);
}
}
private
HlsMasterPlaylist
newSimpleMasterPlaylist
(
String
mediaPlaylistUrl
)
{
return
new
HlsMasterPlaylist
(
Uri
.
parse
(
""
),
Collections
.
singletonList
(
new
Variant
(
0
,
mediaPlaylistUrl
,
0
,
null
,
-
1
,
-
1
)));
}
}
}
demo/src/main/java/com/google/android/exoplayer/demo/simple/SimplePlayerActivity.java
View file @
410fcdeb
...
@@ -166,10 +166,8 @@ public class SimplePlayerActivity extends Activity implements SurfaceHolder.Call
...
@@ -166,10 +166,8 @@ public class SimplePlayerActivity extends Activity implements SurfaceHolder.Call
contentId
);
contentId
);
case
DemoUtil
.
TYPE_DASH_VOD
:
case
DemoUtil
.
TYPE_DASH_VOD
:
return
new
DashVodRendererBuilder
(
this
,
userAgent
,
contentUri
.
toString
(),
contentId
);
return
new
DashVodRendererBuilder
(
this
,
userAgent
,
contentUri
.
toString
(),
contentId
);
case
DemoUtil
.
TYPE_HLS_MASTER
:
case
DemoUtil
.
TYPE_HLS
:
case
DemoUtil
.
TYPE_HLS_MEDIA
:
return
new
HlsRendererBuilder
(
this
,
userAgent
,
contentUri
.
toString
(),
contentId
);
return
new
HlsRendererBuilder
(
this
,
userAgent
,
contentUri
.
toString
(),
contentId
,
contentType
);
default
:
default
:
return
new
DefaultRendererBuilder
(
this
,
contentUri
);
return
new
DefaultRendererBuilder
(
this
,
contentUri
);
}
}
...
...
library/src/main/java/com/google/android/exoplayer/hls/HlsChunkSource.java
View file @
410fcdeb
...
@@ -23,6 +23,7 @@ import com.google.android.exoplayer.upstream.Aes128DataSource;
...
@@ -23,6 +23,7 @@ import com.google.android.exoplayer.upstream.Aes128DataSource;
import
com.google.android.exoplayer.upstream.BandwidthMeter
;
import
com.google.android.exoplayer.upstream.BandwidthMeter
;
import
com.google.android.exoplayer.upstream.DataSource
;
import
com.google.android.exoplayer.upstream.DataSource
;
import
com.google.android.exoplayer.upstream.DataSpec
;
import
com.google.android.exoplayer.upstream.DataSpec
;
import
com.google.android.exoplayer.util.Assertions
;
import
com.google.android.exoplayer.util.BitArray
;
import
com.google.android.exoplayer.util.BitArray
;
import
com.google.android.exoplayer.util.Util
;
import
com.google.android.exoplayer.util.Util
;
...
@@ -51,7 +52,7 @@ public class HlsChunkSource {
...
@@ -51,7 +52,7 @@ public class HlsChunkSource {
private
final
SamplePool
samplePool
=
new
TsExtractor
.
SamplePool
();
private
final
SamplePool
samplePool
=
new
TsExtractor
.
SamplePool
();
private
final
DataSource
upstreamDataSource
;
private
final
DataSource
upstreamDataSource
;
private
final
Hls
MediaPlaylistParser
mediaP
laylistParser
;
private
final
Hls
PlaylistParser
p
laylistParser
;
private
final
Variant
[]
enabledVariants
;
private
final
Variant
[]
enabledVariants
;
private
final
BandwidthMeter
bandwidthMeter
;
private
final
BandwidthMeter
bandwidthMeter
;
private
final
BitArray
bitArray
;
private
final
BitArray
bitArray
;
...
@@ -73,21 +74,32 @@ public class HlsChunkSource {
...
@@ -73,21 +74,32 @@ public class HlsChunkSource {
/**
/**
* @param dataSource A {@link DataSource} suitable for loading the media data.
* @param dataSource A {@link DataSource} suitable for loading the media data.
* @param masterPlaylist The master playlist.
* @param playlistUrl The playlist URL.
* @param playlist The hls playlist.
* @param bandwidthMeter provides an estimate of the currently available bandwidth.
* @param variantIndices A subset of variant indices to consider, or null to consider all of the
* @param variantIndices A subset of variant indices to consider, or null to consider all of the
* variants in the master playlist.
* variants in the master playlist.
*/
*/
public
HlsChunkSource
(
DataSource
dataSource
,
HlsMasterPlaylist
masterP
laylist
,
public
HlsChunkSource
(
DataSource
dataSource
,
String
playlistUrl
,
HlsPlaylist
p
laylist
,
BandwidthMeter
bandwidthMeter
,
int
[]
variantIndices
,
boolean
enableAdaptive
)
{
BandwidthMeter
bandwidthMeter
,
int
[]
variantIndices
,
boolean
enableAdaptive
)
{
this
.
upstreamDataSource
=
dataSource
;
this
.
upstreamDataSource
=
dataSource
;
this
.
bandwidthMeter
=
bandwidthMeter
;
this
.
bandwidthMeter
=
bandwidthMeter
;
this
.
enableAdaptive
=
enableAdaptive
;
this
.
enableAdaptive
=
enableAdaptive
;
baseUri
=
masterP
laylist
.
baseUri
;
baseUri
=
p
laylist
.
baseUri
;
bitArray
=
new
BitArray
();
bitArray
=
new
BitArray
();
mediaPlaylistParser
=
new
HlsMediaPlaylistParser
();
playlistParser
=
new
HlsPlaylistParser
();
enabledVariants
=
filterVariants
(
masterPlaylist
,
variantIndices
);
if
(
playlist
.
type
==
HlsPlaylist
.
TYPE_MEDIA
)
{
enabledVariants
=
new
Variant
[]
{
new
Variant
(
0
,
playlistUrl
,
0
,
null
,
-
1
,
-
1
)};
mediaPlaylists
=
new
HlsMediaPlaylist
[]
{(
HlsMediaPlaylist
)
playlist
};
}
else
{
Assertions
.
checkState
(
playlist
.
type
==
HlsPlaylist
.
TYPE_MASTER
);
enabledVariants
=
filterVariants
((
HlsMasterPlaylist
)
playlist
,
variantIndices
);
mediaPlaylists
=
new
HlsMediaPlaylist
[
enabledVariants
.
length
];
}
lastMediaPlaylistLoadTimesMs
=
new
long
[
enabledVariants
.
length
];
lastMediaPlaylistLoadTimesMs
=
new
long
[
enabledVariants
.
length
];
mediaPlaylists
=
new
HlsMediaPlaylist
[
enabledVariants
.
length
];
int
maxWidth
=
-
1
;
int
maxWidth
=
-
1
;
int
maxHeight
=
-
1
;
int
maxHeight
=
-
1
;
// Select the first variant from the master playlist that's enabled.
// Select the first variant from the master playlist that's enabled.
...
@@ -391,9 +403,11 @@ public class HlsChunkSource {
...
@@ -391,9 +403,11 @@ public class HlsChunkSource {
@Override
@Override
protected
void
consume
(
BitArray
data
)
throws
IOException
{
protected
void
consume
(
BitArray
data
)
throws
IOException
{
Hls
MediaPlaylist
mediaPlaylist
=
mediaP
laylistParser
.
parse
(
Hls
Playlist
playlist
=
p
laylistParser
.
parse
(
new
ByteArrayInputStream
(
data
.
getData
(),
0
,
data
.
bytesLeft
()),
null
,
null
,
new
ByteArrayInputStream
(
data
.
getData
(),
0
,
data
.
bytesLeft
()),
null
,
null
,
playlistBaseUri
);
playlistBaseUri
);
Assertions
.
checkState
(
playlist
.
type
==
HlsPlaylist
.
TYPE_MEDIA
);
HlsMediaPlaylist
mediaPlaylist
=
(
HlsMediaPlaylist
)
playlist
;
mediaPlaylists
[
variantIndex
]
=
mediaPlaylist
;
mediaPlaylists
[
variantIndex
]
=
mediaPlaylist
;
lastMediaPlaylistLoadTimesMs
[
variantIndex
]
=
SystemClock
.
elapsedRealtime
();
lastMediaPlaylistLoadTimesMs
[
variantIndex
]
=
SystemClock
.
elapsedRealtime
();
live
|=
mediaPlaylist
.
live
;
live
|=
mediaPlaylist
.
live
;
...
...
library/src/main/java/com/google/android/exoplayer/hls/HlsMasterPlaylist.java
View file @
410fcdeb
...
@@ -22,13 +22,12 @@ import java.util.List;
...
@@ -22,13 +22,12 @@ import java.util.List;
/**
/**
* Represents an HLS master playlist.
* Represents an HLS master playlist.
*/
*/
public
final
class
HlsMasterPlaylist
{
public
final
class
HlsMasterPlaylist
extends
HlsPlaylist
{
public
final
Uri
baseUri
;
public
final
List
<
Variant
>
variants
;
public
final
List
<
Variant
>
variants
;
public
HlsMasterPlaylist
(
Uri
baseUri
,
List
<
Variant
>
variants
)
{
public
HlsMasterPlaylist
(
Uri
baseUri
,
List
<
Variant
>
variants
)
{
this
.
baseUri
=
baseUri
;
super
(
baseUri
,
HlsPlaylist
.
TYPE_MASTER
)
;
this
.
variants
=
variants
;
this
.
variants
=
variants
;
}
}
...
...
library/src/main/java/com/google/android/exoplayer/hls/HlsMasterPlaylistParser.java
deleted
100644 → 0
View file @
f9f3b82d
/*
* 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
.
hls
;
import
com.google.android.exoplayer.util.ManifestParser
;
import
android.net.Uri
;
import
java.io.BufferedReader
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.InputStreamReader
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.regex.Pattern
;
/**
* HLS Master playlists parsing logic.
*/
public
final
class
HlsMasterPlaylistParser
implements
ManifestParser
<
HlsMasterPlaylist
>
{
private
static
final
String
STREAM_INF_TAG
=
"#EXT-X-STREAM-INF"
;
private
static
final
String
BANDWIDTH_ATTR
=
"BANDWIDTH"
;
private
static
final
String
CODECS_ATTR
=
"CODECS"
;
private
static
final
String
RESOLUTION_ATTR
=
"RESOLUTION"
;
private
static
final
Pattern
BANDWIDTH_ATTR_REGEX
=
Pattern
.
compile
(
BANDWIDTH_ATTR
+
"=(\\d+)\\b"
);
private
static
final
Pattern
CODECS_ATTR_REGEX
=
Pattern
.
compile
(
CODECS_ATTR
+
"=\"(.+)\""
);
private
static
final
Pattern
RESOLUTION_ATTR_REGEX
=
Pattern
.
compile
(
RESOLUTION_ATTR
+
"=(\\d+x\\d+)"
);
@Override
public
HlsMasterPlaylist
parse
(
InputStream
inputStream
,
String
inputEncoding
,
String
contentId
,
Uri
baseUri
)
throws
IOException
{
return
parseMasterPlaylist
(
inputStream
,
inputEncoding
,
baseUri
);
}
private
static
HlsMasterPlaylist
parseMasterPlaylist
(
InputStream
inputStream
,
String
inputEncoding
,
Uri
baseUri
)
throws
IOException
{
BufferedReader
reader
=
new
BufferedReader
((
inputEncoding
==
null
)
?
new
InputStreamReader
(
inputStream
)
:
new
InputStreamReader
(
inputStream
,
inputEncoding
));
List
<
Variant
>
variants
=
new
ArrayList
<
Variant
>();
int
bandwidth
=
0
;
String
[]
codecs
=
null
;
int
width
=
-
1
;
int
height
=
-
1
;
int
variantIndex
=
0
;
String
line
;
while
((
line
=
reader
.
readLine
())
!=
null
)
{
line
=
line
.
trim
();
if
(
line
.
isEmpty
())
{
continue
;
}
if
(
line
.
startsWith
(
STREAM_INF_TAG
))
{
bandwidth
=
HlsParserUtil
.
parseIntAttr
(
line
,
BANDWIDTH_ATTR_REGEX
,
BANDWIDTH_ATTR
);
String
codecsString
=
HlsParserUtil
.
parseOptionalStringAttr
(
line
,
CODECS_ATTR_REGEX
);
if
(
codecsString
!=
null
)
{
codecs
=
codecsString
.
split
(
"(\\s*,\\s*)|(\\s*$)"
);
}
else
{
codecs
=
null
;
}
String
resolutionString
=
HlsParserUtil
.
parseOptionalStringAttr
(
line
,
RESOLUTION_ATTR_REGEX
);
if
(
resolutionString
!=
null
)
{
String
[]
widthAndHeight
=
resolutionString
.
split
(
"x"
);
width
=
Integer
.
parseInt
(
widthAndHeight
[
0
]);
height
=
Integer
.
parseInt
(
widthAndHeight
[
1
]);
}
else
{
width
=
-
1
;
height
=
-
1
;
}
}
else
if
(!
line
.
startsWith
(
"#"
))
{
variants
.
add
(
new
Variant
(
variantIndex
++,
line
,
bandwidth
,
codecs
,
width
,
height
));
bandwidth
=
0
;
codecs
=
null
;
width
=
-
1
;
height
=
-
1
;
}
}
return
new
HlsMasterPlaylist
(
baseUri
,
Collections
.
unmodifiableList
(
variants
));
}
}
library/src/main/java/com/google/android/exoplayer/hls/HlsMediaPlaylist.java
View file @
410fcdeb
...
@@ -22,7 +22,7 @@ import java.util.List;
...
@@ -22,7 +22,7 @@ import java.util.List;
/**
/**
* Represents an HLS media playlist.
* Represents an HLS media playlist.
*/
*/
public
final
class
HlsMediaPlaylist
{
public
final
class
HlsMediaPlaylist
extends
HlsPlaylist
{
/**
/**
* Media segment reference.
* Media segment reference.
...
@@ -61,7 +61,6 @@ public final class HlsMediaPlaylist {
...
@@ -61,7 +61,6 @@ public final class HlsMediaPlaylist {
public
static
final
String
ENCRYPTION_METHOD_NONE
=
"NONE"
;
public
static
final
String
ENCRYPTION_METHOD_NONE
=
"NONE"
;
public
static
final
String
ENCRYPTION_METHOD_AES_128
=
"AES-128"
;
public
static
final
String
ENCRYPTION_METHOD_AES_128
=
"AES-128"
;
public
final
Uri
baseUri
;
public
final
int
mediaSequence
;
public
final
int
mediaSequence
;
public
final
int
targetDurationSecs
;
public
final
int
targetDurationSecs
;
public
final
int
version
;
public
final
int
version
;
...
@@ -71,7 +70,7 @@ public final class HlsMediaPlaylist {
...
@@ -71,7 +70,7 @@ public final class HlsMediaPlaylist {
public
HlsMediaPlaylist
(
Uri
baseUri
,
int
mediaSequence
,
int
targetDurationSecs
,
int
version
,
public
HlsMediaPlaylist
(
Uri
baseUri
,
int
mediaSequence
,
int
targetDurationSecs
,
int
version
,
boolean
live
,
List
<
Segment
>
segments
)
{
boolean
live
,
List
<
Segment
>
segments
)
{
this
.
baseUri
=
baseUri
;
super
(
baseUri
,
HlsPlaylist
.
TYPE_MEDIA
)
;
this
.
mediaSequence
=
mediaSequence
;
this
.
mediaSequence
=
mediaSequence
;
this
.
targetDurationSecs
=
targetDurationSecs
;
this
.
targetDurationSecs
=
targetDurationSecs
;
this
.
version
=
version
;
this
.
version
=
version
;
...
...
library/src/main/java/com/google/android/exoplayer/hls/HlsPlaylist.java
0 → 100644
View file @
410fcdeb
/*
* 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
.
hls
;
import
android.net.Uri
;
/**
* Represents an HLS playlist.
*/
public
abstract
class
HlsPlaylist
{
public
final
static
int
TYPE_MASTER
=
0
;
public
final
static
int
TYPE_MEDIA
=
1
;
public
final
Uri
baseUri
;
public
final
int
type
;
protected
HlsPlaylist
(
Uri
baseUri
,
int
type
)
{
this
.
baseUri
=
baseUri
;
this
.
type
=
type
;
}
}
library/src/main/java/com/google/android/exoplayer/hls/Hls
Media
PlaylistParser.java
→
library/src/main/java/com/google/android/exoplayer/hls/HlsPlaylistParser.java
View file @
410fcdeb
...
@@ -16,6 +16,7 @@
...
@@ -16,6 +16,7 @@
package
com
.
google
.
android
.
exoplayer
.
hls
;
package
com
.
google
.
android
.
exoplayer
.
hls
;
import
com.google.android.exoplayer.C
;
import
com.google.android.exoplayer.C
;
import
com.google.android.exoplayer.ParserException
;
import
com.google.android.exoplayer.hls.HlsMediaPlaylist.Segment
;
import
com.google.android.exoplayer.hls.HlsMediaPlaylist.Segment
;
import
com.google.android.exoplayer.util.ManifestParser
;
import
com.google.android.exoplayer.util.ManifestParser
;
...
@@ -27,19 +28,27 @@ import java.io.InputStream;
...
@@ -27,19 +28,27 @@ import java.io.InputStream;
import
java.io.InputStreamReader
;
import
java.io.InputStreamReader
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.Collections
;
import
java.util.LinkedList
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Queue
;
import
java.util.regex.Pattern
;
import
java.util.regex.Pattern
;
/**
/**
* HLS
Media
playlists parsing logic.
* HLS playlists parsing logic.
*/
*/
public
final
class
HlsMediaPlaylistParser
implements
ManifestParser
<
HlsMediaPlaylist
>
{
public
final
class
HlsPlaylistParser
implements
ManifestParser
<
HlsPlaylist
>
{
private
static
final
String
VERSION_TAG
=
"#EXT-X-VERSION"
;
private
static
final
String
STREAM_INF_TAG
=
"#EXT-X-STREAM-INF"
;
private
static
final
String
BANDWIDTH_ATTR
=
"BANDWIDTH"
;
private
static
final
String
CODECS_ATTR
=
"CODECS"
;
private
static
final
String
RESOLUTION_ATTR
=
"RESOLUTION"
;
private
static
final
String
DISCONTINUITY_TAG
=
"#EXT-X-DISCONTINUITY"
;
private
static
final
String
DISCONTINUITY_TAG
=
"#EXT-X-DISCONTINUITY"
;
private
static
final
String
MEDIA_DURATION_TAG
=
"#EXTINF"
;
private
static
final
String
MEDIA_DURATION_TAG
=
"#EXTINF"
;
private
static
final
String
MEDIA_SEQUENCE_TAG
=
"#EXT-X-MEDIA-SEQUENCE"
;
private
static
final
String
MEDIA_SEQUENCE_TAG
=
"#EXT-X-MEDIA-SEQUENCE"
;
private
static
final
String
TARGET_DURATION_TAG
=
"#EXT-X-TARGETDURATION"
;
private
static
final
String
TARGET_DURATION_TAG
=
"#EXT-X-TARGETDURATION"
;
private
static
final
String
VERSION_TAG
=
"#EXT-X-VERSION"
;
private
static
final
String
ENDLIST_TAG
=
"#EXT-X-ENDLIST"
;
private
static
final
String
ENDLIST_TAG
=
"#EXT-X-ENDLIST"
;
private
static
final
String
KEY_TAG
=
"#EXT-X-KEY"
;
private
static
final
String
KEY_TAG
=
"#EXT-X-KEY"
;
private
static
final
String
BYTERANGE_TAG
=
"#EXT-X-BYTERANGE"
;
private
static
final
String
BYTERANGE_TAG
=
"#EXT-X-BYTERANGE"
;
...
@@ -48,6 +57,13 @@ public final class HlsMediaPlaylistParser implements ManifestParser<HlsMediaPlay
...
@@ -48,6 +57,13 @@ public final class HlsMediaPlaylistParser implements ManifestParser<HlsMediaPlay
private
static
final
String
URI_ATTR
=
"URI"
;
private
static
final
String
URI_ATTR
=
"URI"
;
private
static
final
String
IV_ATTR
=
"IV"
;
private
static
final
String
IV_ATTR
=
"IV"
;
private
static
final
Pattern
BANDWIDTH_ATTR_REGEX
=
Pattern
.
compile
(
BANDWIDTH_ATTR
+
"=(\\d+)\\b"
);
private
static
final
Pattern
CODECS_ATTR_REGEX
=
Pattern
.
compile
(
CODECS_ATTR
+
"=\"(.+)\""
);
private
static
final
Pattern
RESOLUTION_ATTR_REGEX
=
Pattern
.
compile
(
RESOLUTION_ATTR
+
"=(\\d+x\\d+)"
);
private
static
final
Pattern
MEDIA_DURATION_REGEX
=
private
static
final
Pattern
MEDIA_DURATION_REGEX
=
Pattern
.
compile
(
MEDIA_DURATION_TAG
+
":([\\d.]+),"
);
Pattern
.
compile
(
MEDIA_DURATION_TAG
+
":([\\d.]+),"
);
private
static
final
Pattern
MEDIA_SEQUENCE_REGEX
=
private
static
final
Pattern
MEDIA_SEQUENCE_REGEX
=
...
@@ -67,16 +83,84 @@ public final class HlsMediaPlaylistParser implements ManifestParser<HlsMediaPlay
...
@@ -67,16 +83,84 @@ public final class HlsMediaPlaylistParser implements ManifestParser<HlsMediaPlay
Pattern
.
compile
(
IV_ATTR
+
"=([^,.*]+)"
);
Pattern
.
compile
(
IV_ATTR
+
"=([^,.*]+)"
);
@Override
@Override
public
Hls
Media
Playlist
parse
(
InputStream
inputStream
,
String
inputEncoding
,
public
HlsPlaylist
parse
(
InputStream
inputStream
,
String
inputEncoding
,
String
contentId
,
Uri
baseUri
)
throws
IOException
{
String
contentId
,
Uri
baseUri
)
throws
IOException
{
return
parseMediaPlaylist
(
inputStream
,
inputEncoding
,
baseUri
);
}
private
static
HlsMediaPlaylist
parseMediaPlaylist
(
InputStream
inputStream
,
String
inputEncoding
,
Uri
baseUri
)
throws
IOException
{
BufferedReader
reader
=
new
BufferedReader
((
inputEncoding
==
null
)
BufferedReader
reader
=
new
BufferedReader
((
inputEncoding
==
null
)
?
new
InputStreamReader
(
inputStream
)
:
new
InputStreamReader
(
inputStream
,
inputEncoding
));
?
new
InputStreamReader
(
inputStream
)
:
new
InputStreamReader
(
inputStream
,
inputEncoding
));
Queue
<
String
>
extraLines
=
new
LinkedList
<
String
>();
String
line
;
try
{
while
((
line
=
reader
.
readLine
())
!=
null
)
{
line
=
line
.
trim
();
if
(
line
.
isEmpty
())
{
// Do nothing.
}
else
if
(
line
.
startsWith
(
STREAM_INF_TAG
))
{
extraLines
.
add
(
line
);
return
parseMasterPlaylist
(
new
LineIterator
(
extraLines
,
reader
),
baseUri
);
}
else
if
(
line
.
startsWith
(
TARGET_DURATION_TAG
)
||
line
.
startsWith
(
MEDIA_SEQUENCE_TAG
)
||
line
.
startsWith
(
MEDIA_DURATION_TAG
)
||
line
.
startsWith
(
KEY_TAG
)
||
line
.
startsWith
(
BYTERANGE_TAG
)
||
line
.
equals
(
DISCONTINUITY_TAG
)
||
line
.
equals
(
ENDLIST_TAG
))
{
extraLines
.
add
(
line
);
return
parseMediaPlaylist
(
new
LineIterator
(
extraLines
,
reader
),
baseUri
);
}
else
if
(
line
.
startsWith
(
VERSION_TAG
))
{
extraLines
.
add
(
line
);
}
else
if
(!
line
.
startsWith
(
"#"
))
{
throw
new
ParserException
(
"Missing a tag before URL."
);
}
}
}
finally
{
reader
.
close
();
}
throw
new
ParserException
(
"Failed to parse the playlist, could not identify any tags."
);
}
private
static
HlsMasterPlaylist
parseMasterPlaylist
(
LineIterator
iterator
,
Uri
baseUri
)
throws
IOException
{
List
<
Variant
>
variants
=
new
ArrayList
<
Variant
>();
int
bandwidth
=
0
;
String
[]
codecs
=
null
;
int
width
=
-
1
;
int
height
=
-
1
;
int
variantIndex
=
0
;
String
line
;
while
(
iterator
.
hasNext
())
{
line
=
iterator
.
next
();
if
(
line
.
startsWith
(
STREAM_INF_TAG
))
{
bandwidth
=
HlsParserUtil
.
parseIntAttr
(
line
,
BANDWIDTH_ATTR_REGEX
,
BANDWIDTH_ATTR
);
String
codecsString
=
HlsParserUtil
.
parseOptionalStringAttr
(
line
,
CODECS_ATTR_REGEX
);
if
(
codecsString
!=
null
)
{
codecs
=
codecsString
.
split
(
"(\\s*,\\s*)|(\\s*$)"
);
}
else
{
codecs
=
null
;
}
String
resolutionString
=
HlsParserUtil
.
parseOptionalStringAttr
(
line
,
RESOLUTION_ATTR_REGEX
);
if
(
resolutionString
!=
null
)
{
String
[]
widthAndHeight
=
resolutionString
.
split
(
"x"
);
width
=
Integer
.
parseInt
(
widthAndHeight
[
0
]);
height
=
Integer
.
parseInt
(
widthAndHeight
[
1
]);
}
else
{
width
=
-
1
;
height
=
-
1
;
}
}
else
if
(!
line
.
startsWith
(
"#"
))
{
variants
.
add
(
new
Variant
(
variantIndex
++,
line
,
bandwidth
,
codecs
,
width
,
height
));
bandwidth
=
0
;
codecs
=
null
;
width
=
-
1
;
height
=
-
1
;
}
}
return
new
HlsMasterPlaylist
(
baseUri
,
Collections
.
unmodifiableList
(
variants
));
}
private
static
HlsMediaPlaylist
parseMediaPlaylist
(
LineIterator
iterator
,
Uri
baseUri
)
throws
IOException
{
int
mediaSequence
=
0
;
int
mediaSequence
=
0
;
int
targetDurationSecs
=
0
;
int
targetDurationSecs
=
0
;
int
version
=
1
;
// Default version == 1.
int
version
=
1
;
// Default version == 1.
...
@@ -95,11 +179,8 @@ public final class HlsMediaPlaylistParser implements ManifestParser<HlsMediaPlay
...
@@ -95,11 +179,8 @@ public final class HlsMediaPlaylistParser implements ManifestParser<HlsMediaPlay
int
segmentMediaSequence
=
0
;
int
segmentMediaSequence
=
0
;
String
line
;
String
line
;
while
((
line
=
reader
.
readLine
())
!=
null
)
{
while
(
iterator
.
hasNext
())
{
line
=
line
.
trim
();
line
=
iterator
.
next
();
if
(
line
.
isEmpty
())
{
continue
;
}
if
(
line
.
startsWith
(
TARGET_DURATION_TAG
))
{
if
(
line
.
startsWith
(
TARGET_DURATION_TAG
))
{
targetDurationSecs
=
HlsParserUtil
.
parseIntAttr
(
line
,
TARGET_DURATION_REGEX
,
targetDurationSecs
=
HlsParserUtil
.
parseIntAttr
(
line
,
TARGET_DURATION_REGEX
,
TARGET_DURATION_TAG
);
TARGET_DURATION_TAG
);
...
@@ -158,4 +239,44 @@ public final class HlsMediaPlaylistParser implements ManifestParser<HlsMediaPlay
...
@@ -158,4 +239,44 @@ public final class HlsMediaPlaylistParser implements ManifestParser<HlsMediaPlay
Collections
.
unmodifiableList
(
segments
));
Collections
.
unmodifiableList
(
segments
));
}
}
private
static
class
LineIterator
{
private
final
BufferedReader
reader
;
private
final
Queue
<
String
>
extraLines
;
private
String
next
;
public
LineIterator
(
Queue
<
String
>
extraLines
,
BufferedReader
reader
)
{
this
.
extraLines
=
extraLines
;
this
.
reader
=
reader
;
}
public
boolean
hasNext
()
throws
IOException
{
if
(
next
!=
null
)
{
return
true
;
}
if
(!
extraLines
.
isEmpty
())
{
next
=
extraLines
.
poll
();
return
true
;
}
while
((
next
=
reader
.
readLine
())
!=
null
)
{
next
=
next
.
trim
();
if
(!
next
.
isEmpty
())
{
return
true
;
}
}
return
false
;
}
public
String
next
()
throws
IOException
{
String
result
=
null
;
if
(
hasNext
())
{
result
=
next
;
next
=
null
;
}
return
result
;
}
}
}
}
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