feat: added HLS playback support
This commit is contained in:
parent
3730804c8f
commit
9870fe3f18
@ -241,17 +241,29 @@ public class VideoPlayerFragment extends Fragment implements VideoRendererEventL
|
|||||||
|
|
||||||
Integer videoQuality = sharedPref.getInt(getString(R.string.pref_quality_key), 999999);
|
Integer videoQuality = sharedPref.getInt(getString(R.string.pref_quality_key), 999999);
|
||||||
|
|
||||||
|
String urlToPlay = null;
|
||||||
|
boolean isHLS = false;
|
||||||
|
|
||||||
|
// try HLS stream first
|
||||||
// get video qualities
|
// get video qualities
|
||||||
// TODO: if auto is set all versions except 0p should be added to a track and have exoplayer auto select optimal bitrate
|
// TODO: if auto is set all versions except 0p should be added to a track and have exoplayer auto select optimal bitrate
|
||||||
if (video.getFiles().size() > 0) {
|
if (video.getStreamingPlaylists().size() > 0) {
|
||||||
String urlToPlay = video.getFiles().get( 0 ).getFileUrl(); // default, take first found, usually highest res
|
urlToPlay = video.getStreamingPlaylists().get( 0 ).getPlaylistUrl();
|
||||||
for ( File file : video.getFiles() ) {
|
isHLS = true;
|
||||||
// Set quality if it matches
|
} else {
|
||||||
if ( file.getResolution().getId().equals( videoQuality ) ) {
|
if (video.getFiles().size() > 0) {
|
||||||
urlToPlay = file.getFileUrl();
|
urlToPlay = video.getFiles().get( 0 ).getFileUrl(); // default, take first found, usually highest res
|
||||||
|
for ( File file : video.getFiles() ) {
|
||||||
|
// Set quality if it matches
|
||||||
|
if ( file.getResolution().getId().equals( videoQuality ) ) {
|
||||||
|
urlToPlay = file.getFileUrl();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mService.setCurrentStreamUrl( urlToPlay );
|
}
|
||||||
|
|
||||||
|
if (!urlToPlay.isEmpty()) {
|
||||||
|
mService.setCurrentStreamUrl( urlToPlay, isHLS);
|
||||||
torrentStatus.setVisibility(View.GONE);
|
torrentStatus.setVisibility(View.GONE);
|
||||||
startPlayer();
|
startPlayer();
|
||||||
} else {
|
} else {
|
||||||
@ -357,7 +369,7 @@ public class VideoPlayerFragment extends Fragment implements VideoRendererEventL
|
|||||||
public void onStreamReady(Torrent torrent) {
|
public void onStreamReady(Torrent torrent) {
|
||||||
String videopath = Uri.fromFile(torrent.getVideoFile()).toString();
|
String videopath = Uri.fromFile(torrent.getVideoFile()).toString();
|
||||||
Log.d(TAG, "Ready! torrentStream videopath:" + videopath);
|
Log.d(TAG, "Ready! torrentStream videopath:" + videopath);
|
||||||
mService.setCurrentStreamUrl(videopath);
|
mService.setCurrentStreamUrl(videopath, false);
|
||||||
startPlayer();
|
startPlayer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
39
app/src/main/java/net/schueller/peertube/model/State.java
Normal file
39
app/src/main/java/net/schueller/peertube/model/State.java
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 Stefan Schüller <sschueller@techdroid.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package net.schueller.peertube.model;
|
||||||
|
|
||||||
|
public class State {
|
||||||
|
|
||||||
|
private Integer id;
|
||||||
|
private String label;
|
||||||
|
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLabel() {
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLabel(String label) {
|
||||||
|
this.label = label;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 Stefan Schüller <sschueller@techdroid.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package net.schueller.peertube.model;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class StreamingPlaylist {
|
||||||
|
|
||||||
|
private Integer id;
|
||||||
|
private Integer type;
|
||||||
|
private String playlistUrl;
|
||||||
|
private String segmentsSha256Url;
|
||||||
|
private ArrayList<String> redundancies;
|
||||||
|
private ArrayList<File> files;
|
||||||
|
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(final Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(final Integer type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPlaylistUrl() {
|
||||||
|
return playlistUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPlaylistUrl(final String playlistUrl) {
|
||||||
|
this.playlistUrl = playlistUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSegmentsSha256Url() {
|
||||||
|
return segmentsSha256Url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSegmentsSha256Url(final String segmentsSha256Url) {
|
||||||
|
this.segmentsSha256Url = segmentsSha256Url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<String> getRedundancies() {
|
||||||
|
return redundancies;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRedundancies(final ArrayList<String> redundancies) {
|
||||||
|
this.redundancies = redundancies;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<File> getFiles() {
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFiles(final ArrayList<File> files) {
|
||||||
|
this.files = files;
|
||||||
|
}
|
||||||
|
}
|
@ -60,11 +60,19 @@ public class Video {
|
|||||||
|
|
||||||
private Channel channel;
|
private Channel channel;
|
||||||
private Account account;
|
private Account account;
|
||||||
private ArrayList tags;
|
private ArrayList<String> tags;
|
||||||
|
|
||||||
private Boolean commentsEnabled;
|
private Boolean commentsEnabled;
|
||||||
|
private Boolean downloadEnabled;
|
||||||
|
private Boolean waitTranscoding;
|
||||||
|
|
||||||
|
private State state;
|
||||||
|
private ArrayList<String> trackerUrls;
|
||||||
|
|
||||||
private ArrayList<File> files;
|
private ArrayList<File> files;
|
||||||
|
|
||||||
|
private ArrayList<StreamingPlaylist> streamingPlaylists;
|
||||||
|
|
||||||
public Video() {
|
public Video() {
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -253,11 +261,11 @@ public class Video {
|
|||||||
this.account = account;
|
this.account = account;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList getTags() {
|
public ArrayList<String> getTags() {
|
||||||
return tags;
|
return tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTags(ArrayList tags) {
|
public void setTags(ArrayList<String> tags) {
|
||||||
this.tags = tags;
|
this.tags = tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,7 +285,45 @@ public class Video {
|
|||||||
this.files = files;
|
this.files = files;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Boolean getDownloadEnabled() {
|
||||||
|
return downloadEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDownloadEnabled(final Boolean downloadEnabled) {
|
||||||
|
this.downloadEnabled = downloadEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getWaitTranscoding() {
|
||||||
|
return waitTranscoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWaitTranscoding(final Boolean waitTranscoding) {
|
||||||
|
this.waitTranscoding = waitTranscoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public State getState() {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setState(final State state) {
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<String> getTrackerUrls() {
|
||||||
|
return trackerUrls;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTrackerUrls(final ArrayList<String> trackerUrls) {
|
||||||
|
this.trackerUrls = trackerUrls;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<StreamingPlaylist> getStreamingPlaylists() {
|
||||||
|
return streamingPlaylists;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStreamingPlaylists(final ArrayList<StreamingPlaylist> streamingPlaylists) {
|
||||||
|
this.streamingPlaylists = streamingPlaylists;
|
||||||
|
}
|
||||||
|
|
||||||
public static MediaDescriptionCompat getMediaDescription(Context context, Video video) {
|
public static MediaDescriptionCompat getMediaDescription(Context context, Video video) {
|
||||||
|
|
||||||
|
@ -56,6 +56,7 @@ import com.google.android.exoplayer2.ext.okhttp.OkHttpDataSourceFactory;
|
|||||||
import com.google.android.exoplayer2.source.ExtractorMediaSource;
|
import com.google.android.exoplayer2.source.ExtractorMediaSource;
|
||||||
import com.google.android.exoplayer2.source.MediaSource;
|
import com.google.android.exoplayer2.source.MediaSource;
|
||||||
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
|
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
|
||||||
|
import com.google.android.exoplayer2.source.hls.HlsMediaSource;
|
||||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
|
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
|
||||||
import com.google.android.exoplayer2.ui.PlayerNotificationManager;
|
import com.google.android.exoplayer2.ui.PlayerNotificationManager;
|
||||||
import com.google.android.exoplayer2.upstream.DataSource;
|
import com.google.android.exoplayer2.upstream.DataSource;
|
||||||
@ -93,6 +94,8 @@ public class VideoPlayerService extends Service {
|
|||||||
|
|
||||||
private String currentStreamUrl;
|
private String currentStreamUrl;
|
||||||
|
|
||||||
|
private boolean currentStreamUrlIsHLS;
|
||||||
|
|
||||||
private PlayerNotificationManager playerNotificationManager;
|
private PlayerNotificationManager playerNotificationManager;
|
||||||
|
|
||||||
private IntentFilter becomeNoisyIntentFilter = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
|
private IntentFilter becomeNoisyIntentFilter = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
|
||||||
@ -190,8 +193,9 @@ public class VideoPlayerService extends Service {
|
|||||||
currentVideo = video;
|
currentVideo = video;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCurrentStreamUrl(String streamUrl) {
|
public void setCurrentStreamUrl(String streamUrl, boolean isHLS) {
|
||||||
Log.v(TAG, "setCurrentStreamUrl..." + streamUrl);
|
Log.v(TAG, "setCurrentStreamUrl..." + streamUrl);
|
||||||
|
currentStreamUrlIsHLS = isHLS;
|
||||||
currentStreamUrl = streamUrl;
|
currentStreamUrl = streamUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,8 +237,14 @@ public class VideoPlayerService extends Service {
|
|||||||
DataSource.Factory dataSourceFactory = new OkHttpDataSourceFactory(okhttpClientBuilder.build(), Util.getUserAgent(getApplicationContext(), "PeerTube"));
|
DataSource.Factory dataSourceFactory = new OkHttpDataSourceFactory(okhttpClientBuilder.build(), Util.getUserAgent(getApplicationContext(), "PeerTube"));
|
||||||
|
|
||||||
// Create a progressive media source pointing to a stream uri.
|
// Create a progressive media source pointing to a stream uri.
|
||||||
MediaSource mediaSource = new ProgressiveMediaSource.Factory(dataSourceFactory)
|
MediaSource mediaSource;
|
||||||
.createMediaSource(MediaItem.fromUri(Uri.parse(currentStreamUrl)));
|
if (currentStreamUrlIsHLS) {
|
||||||
|
mediaSource = new HlsMediaSource.Factory(dataSourceFactory)
|
||||||
|
.createMediaSource(MediaItem.fromUri(Uri.parse(currentStreamUrl)));
|
||||||
|
} else {
|
||||||
|
mediaSource = new ProgressiveMediaSource.Factory(dataSourceFactory)
|
||||||
|
.createMediaSource(MediaItem.fromUri(Uri.parse(currentStreamUrl)));
|
||||||
|
}
|
||||||
|
|
||||||
// Set the media source to be played.
|
// Set the media source to be played.
|
||||||
player.setMediaSource(mediaSource);
|
player.setMediaSource(mediaSource);
|
||||||
|
Loading…
Reference in New Issue
Block a user