This commit is contained in:
Yuriy Liskov
2021-05-28 17:43:32 +03:00
parent d8c49b76c7
commit 2a17a31b13
8 changed files with 122 additions and 16 deletions

View File

@@ -1,3 +1,5 @@
apply from: gradle.ext.sharedModulesConstants
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {

View File

@@ -55,14 +55,21 @@ dependencies {
implementation 'io.reactivex.rxjava2:rxandroid:' + rxAndroidVersion
implementation 'io.reactivex.rxjava2:rxjava:' + rxJavaVersion
implementation 'com.amazon.android:exoplayer:' + amazonExoplayerVersion
implementation 'com.amazon.android:extension-okhttp:' + amazonExoplayerVersion
//////// BEGIN EXOPLAYER /////////
// implementation 'com.amazon.android:exoplayer:' + amazonExoplayerVersion
// implementation 'com.amazon.android:extension-okhttp:' + amazonExoplayerVersion
// implementation 'com.google.android.exoplayer:exoplayer:' + exoplayerVersion
// implementation 'com.google.android.exoplayer:extension-okhttp:' + exoplayerVersion
// implementation 'com.github.amzn:exoplayer-amazon-port:' + amazonExoplayerJitpackVersion
implementation project(':exoplayer-library')
implementation project(':exoplayer-extension-okhttp')
//////// END EXOPLAYER //////////
implementation 'androidx.media:media:' + mediaXLibraryVersion // exoplayer fix
implementation 'com.github.bumptech.glide:glide:' + glideVersion

View File

@@ -29,6 +29,7 @@ import java.util.Map;
public class VideoLoader extends PlayerEventListenerHelper {
private static final String TAG = VideoLoader.class.getSimpleName();
private static final boolean ENABLE_4K_FIX = false;
private static final int BUFFERING_CHECK_MS = 5_000;
private final Playlist mPlaylist;
private final Handler mHandler;
private final SuggestionsLoader mSuggestionsLoader;
@@ -108,7 +109,7 @@ public class VideoLoader extends PlayerEventListenerHelper {
//MessageHelpers.showMessage(getActivity(), "Buffering occurs!");
// Fix long buffering
Utils.postDelayed(mHandler, mPendingRestartEngine, 10_000);
Utils.postDelayed(mHandler, mPendingRestartEngine, BUFFERING_CHECK_MS);
}
@Override
@@ -280,7 +281,7 @@ public class VideoLoader extends PlayerEventListenerHelper {
private void processFormatInfo(MediaItemFormatInfo formatInfo) {
if (formatInfo.isUnplayable()) {
getController().showError(formatInfo.getPlayabilityStatus());
} else if (ENABLE_4K_FIX && formatInfo.containsDashUrl() && formatInfo.isLive() && formatInfo.isStreamSeekable()) {
} else if (formatInfo.containsDashUrl() && formatInfo.isLive()) {
Log.d(TAG, "Found live video in dash format. Loading...");
getController().openDashUrl(formatInfo.getDashManifestUrl());
} else if (formatInfo.containsHlsUrl()) {

View File

@@ -1,11 +1,11 @@
package com.liskovsoft.smartyoutubetv2.common.exoplayer;
import android.annotation.SuppressLint;
import android.content.Context;
import android.net.Uri;
import android.os.Handler;
import android.text.TextUtils;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ext.okhttp.OkHttpDataSourceFactory;
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
import com.google.android.exoplayer2.source.ConcatenatingMediaSource;
import com.google.android.exoplayer2.source.ExtractorMediaSource;
@@ -31,25 +31,23 @@ import com.google.android.exoplayer2.upstream.HttpDataSource;
import com.google.android.exoplayer2.util.Util;
import com.liskovsoft.sharedutils.helpers.FileHelpers;
import com.liskovsoft.sharedutils.mylogger.Log;
import com.liskovsoft.sharedutils.okhttp.OkHttpHelpers;
import com.liskovsoft.youtubeapi.app.AppConstants;
import com.liskovsoft.youtubeapi.common.helpers.RetrofitHelper;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
public class ExoMediaSourceFactory {
private static final String TAG = ExoMediaSourceFactory.class.getSimpleName();
@SuppressLint("StaticFieldLeak")
private static ExoMediaSourceFactory sInstance;
@SuppressLint("StaticFieldLeak")
@SuppressWarnings("deprecation")
private static final DefaultBandwidthMeter BANDWIDTH_METER = new DefaultBandwidthMeter();
private static final DashManifestParser LIVE_MANIFEST_PARSER = new LiveManifestParser();
private final Factory mMediaDataSourceFactory;
private final Context mContext;
private static final List<String> EXO_HEADERS = Arrays.asList("Origin", "Referer", "User-Agent", "Accept-Language", "Accept", "X-Client-Data");
private static final String SAMSUNG_SMART_TV_UA =
"Mozilla/5.0 (Linux; Tizen 2.3; SmartHub; SMART-TV; SmartTV; U; Maple2012) AppleWebKit/538.1+ (KHTML, like Gecko) TV Safari/538.1+";
//private static final List<String> EXO_HEADERS = Arrays.asList("Origin", "Referer", "User-Agent", "Accept-Language", "Accept", "X-Client-Data");
private static final Uri DASH_MANIFEST_URI = Uri.parse("https://example.com/test.mpd");
private static final String DASH_MANIFEST_EXTENSION = "mpd";
private static final String HLS_PLAYLIST_EXTENSION = "m3u8";
@@ -60,6 +58,12 @@ public class ExoMediaSourceFactory {
private ExoMediaSourceFactory(Context context) {
mContext = context;
mMediaDataSourceFactory = buildDataSourceFactory(USE_BANDWIDTH_METER);
//if (BuildConfig.DEBUG) {
// mMainHandler = new Handler(Looper.getMainLooper());
// mEventLogger = new DefaultMediaSourceEventListener() {
// };
//}
}
public static ExoMediaSourceFactory instance(Context context) {
@@ -148,6 +152,7 @@ public class ExoMediaSourceFactory {
new DefaultDashChunkSource.Factory(mMediaDataSourceFactory),
buildDataSourceFactory(USE_BANDWIDTH_METER)
)
.setManifestParser(LIVE_MANIFEST_PARSER)
.createMediaSource(uri);
if (mEventLogger != null) {
dashSource.addEventListener(mMainHandler, mEventLogger);

View File

@@ -0,0 +1,68 @@
package com.liskovsoft.smartyoutubetv2.common.exoplayer;
import android.net.Uri;
import com.google.android.exoplayer2.source.dash.manifest.AdaptationSet;
import com.google.android.exoplayer2.source.dash.manifest.DashManifest;
import com.google.android.exoplayer2.source.dash.manifest.DashManifestParser;
import com.google.android.exoplayer2.source.dash.manifest.EventStream;
import com.google.android.exoplayer2.source.dash.manifest.Period;
import com.google.android.exoplayer2.source.dash.manifest.ProgramInformation;
import com.google.android.exoplayer2.source.dash.manifest.RangedUri;
import com.google.android.exoplayer2.source.dash.manifest.SegmentBase.SegmentList;
import com.google.android.exoplayer2.source.dash.manifest.SegmentBase.SegmentTemplate;
import com.google.android.exoplayer2.source.dash.manifest.SegmentBase.SegmentTimelineElement;
import com.google.android.exoplayer2.source.dash.manifest.UrlTemplate;
import com.google.android.exoplayer2.source.dash.manifest.UtcTimingElement;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.util.List;
public class LiveManifestParser extends DashManifestParser {
private long mPresentationTimeOffsetMs;
private long mStartNumber;
@Override
protected DashManifest parseMediaPresentationDescription(XmlPullParser xpp, String baseUrl) throws XmlPullParserException, IOException {
return super.parseMediaPresentationDescription(xpp, baseUrl);
}
@Override
protected DashManifest buildMediaPresentationDescription(long availabilityStartTime, long durationMs, long minBufferTimeMs, boolean dynamic,
long minUpdateTimeMs, long timeShiftBufferDepthMs, long suggestedPresentationDelayMs,
long publishTimeMs, ProgramInformation programInformation, UtcTimingElement utcTiming,
Uri location, List<Period> periods) {
return super.buildMediaPresentationDescription(availabilityStartTime, durationMs, minBufferTimeMs, dynamic, minUpdateTimeMs, timeShiftBufferDepthMs, suggestedPresentationDelayMs, publishTimeMs, programInformation, utcTiming, location, periods);
}
@Override
protected SegmentList parseSegmentList(XmlPullParser xpp, SegmentList parent) throws XmlPullParserException, IOException {
return super.parseSegmentList(xpp, parent);
}
//@Override
//protected SegmentList buildSegmentList(RangedUri initialization, long timescale, long presentationTimeOffset, long startNumber, long duration, List<SegmentTimelineElement> timeline, List<RangedUri> segments) {
// if (presentationTimeOffset > 0) {
// mPresentationTimeOffsetMs = presentationTimeOffset;
// }
//
// if (startNumber > 0) {
// mStartNumber = startNumber;
// }
//
// return super.buildSegmentList(initialization, timescale, 0, 0, duration, timeline, segments);
//}
//
//@Override
//protected SegmentTemplate buildSegmentTemplate(RangedUri initialization, long timescale, long presentationTimeOffset, long startNumber,
// long endNumber, long duration, List<SegmentTimelineElement> timeline,
// UrlTemplate initializationTemplate, UrlTemplate mediaTemplate) {
// return super.buildSegmentTemplate(initialization, timescale, 0, 0, endNumber, duration, timeline, initializationTemplate, mediaTemplate);
//}
@Override
protected Period buildPeriod(String id, long startMs, List<AdaptationSet> adaptationSets, List<EventStream> eventStreams) {
return super.buildPeriod(id, 0, adaptationSets, eventStreams);
}
}

View File

@@ -2,12 +2,17 @@ include ':smarttubetv', ':common'
def rootDir = settingsDir
// prepare to git submodule
// git submodule
gradle.ext.sharedModulesRoot = new File(rootDir, '../SharedModules').exists() ? new File(rootDir, '../SharedModules') : new File(rootDir, './SharedModules')
apply from: new File(gradle.ext.sharedModulesRoot, 'core_settings.gradle')
gradle.ext.sharedModulesConstants = new File(gradle.ext.sharedModulesRoot, 'constants.gradle')
// prepare to git submodule
// git submodule
gradle.ext.mediaServiceCoreRoot = new File(rootDir, '../MediaServiceCore').exists() ? new File(rootDir, '../MediaServiceCore') : new File(rootDir, './MediaServiceCore')
apply from: new File(gradle.ext.mediaServiceCoreRoot, 'core_settings.gradle')
// git submodule
gradle.ext.exoplayerRoot = new File(rootDir, '../AmznExoPlayer2.10.6').exists() ? new File(rootDir, '../AmznExoPlayer2.10.6') : new File(rootDir, './AmznExoPlayer2.10.6')
gradle.ext.exoplayerModulePrefix = 'exoplayer-'
apply from: new File(gradle.ext.exoplayerRoot, 'core_settings.gradle')

View File

@@ -125,9 +125,11 @@ dependencies {
annotationProcessor 'com.github.bumptech.glide:compiler:' + glideVersion
implementation 'com.zlc.glide:webpdecoder:2.0.' + glideVersion
implementation 'com.amazon.android:exoplayer:' + amazonExoplayerVersion
implementation 'com.amazon.android:extension-leanback:' + amazonExoplayerVersion
implementation 'com.amazon.android:extension-mediasession:' + amazonExoplayerVersion
//////// BEGIN EXOPLAYER /////////
// implementation 'com.amazon.android:exoplayer:' + amazonExoplayerVersion
// implementation 'com.amazon.android:extension-leanback:' + amazonExoplayerVersion
// implementation 'com.amazon.android:extension-mediasession:' + amazonExoplayerVersion
// implementation 'com.google.android.exoplayer:exoplayer:' + exoplayerVersion
// implementation 'com.google.android.exoplayer:extension-leanback:' + exoplayerVersion
@@ -135,6 +137,12 @@ dependencies {
// implementation 'com.github.amzn:exoplayer-amazon-port:' + amazonExoplayerJitpackVersion
implementation project(':exoplayer-library')
implementation project(':exoplayer-extension-leanback')
implementation project(':exoplayer-extension-mediasession')
//////// END EXOPLAYER //////////
testImplementation 'junit:junit:' + junitVersion
testImplementation 'org.robolectric:robolectric:' + robolectricVersion
androidTestImplementation 'androidx.test.ext:junit:' + testXSupportLibraryVersion

View File

@@ -99,6 +99,7 @@ public class PlaybackFragment extends VideoEventsOverrideFragment implements Pla
private int mPlaybackMode = PlaybackEngineController.BACKGROUND_MODE_DEFAULT;
private MediaSessionCompat mMediaSession;
private MediaSessionConnector mMediaSessionConnector;
private long mLastEngineRestartMs;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -260,6 +261,15 @@ public class PlaybackFragment extends VideoEventsOverrideFragment implements Pla
return;
}
long currentTimeMillis = System.currentTimeMillis();
if (currentTimeMillis - mLastEngineRestartMs < 60_000) {
Log.d(TAG, "Trying not restart engine very often (once per minute)");
return;
}
mLastEngineRestartMs = currentTimeMillis;
if (mPlayer != null) {
mEventListener.onEngineReleased();
}