Guest User

Untitled

a guest
Dec 5th, 2019
101
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2. * Copyright (C) 2016 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.google.android.exoplayer2.demo;
  17.  
  18. import android.content.Intent;
  19. import android.content.pm.PackageManager;
  20. import android.net.Uri;
  21. import android.os.Bundle;
  22. import android.os.Environment;
  23. import android.util.Pair;
  24. import android.view.KeyEvent;
  25. import android.view.View;
  26. import android.view.View.OnClickListener;
  27. import android.widget.Button;
  28. import android.widget.LinearLayout;
  29. import android.widget.TextView;
  30. import android.widget.Toast;
  31. import androidx.annotation.NonNull;
  32. import androidx.annotation.Nullable;
  33. import androidx.appcompat.app.AppCompatActivity;
  34. import com.google.android.exoplayer2.C;
  35. import com.google.android.exoplayer2.C.ContentType;
  36. import com.google.android.exoplayer2.ExoPlaybackException;
  37. import com.google.android.exoplayer2.ExoPlayerFactory;
  38. import com.google.android.exoplayer2.PlaybackPreparer;
  39. import com.google.android.exoplayer2.Player;
  40. import com.google.android.exoplayer2.RenderersFactory;
  41. import com.google.android.exoplayer2.SimpleExoPlayer;
  42. import com.google.android.exoplayer2.demo.test.MyDataSource;
  43. import com.google.android.exoplayer2.drm.DefaultDrmSessionManager;
  44. import com.google.android.exoplayer2.drm.DrmSessionManager;
  45. import com.google.android.exoplayer2.drm.ExoMediaCrypto;
  46. import com.google.android.exoplayer2.drm.FrameworkMediaCrypto;
  47. import com.google.android.exoplayer2.drm.FrameworkMediaDrm;
  48. import com.google.android.exoplayer2.drm.HttpMediaDrmCallback;
  49. import com.google.android.exoplayer2.drm.UnsupportedDrmException;
  50. import com.google.android.exoplayer2.extractor.mp4.Mp4Extractor;
  51. import com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.DecoderInitializationException;
  52. import com.google.android.exoplayer2.mediacodec.MediaCodecUtil.DecoderQueryException;
  53. import com.google.android.exoplayer2.offline.DownloadHelper;
  54. import com.google.android.exoplayer2.offline.DownloadRequest;
  55. import com.google.android.exoplayer2.source.BehindLiveWindowException;
  56. import com.google.android.exoplayer2.source.MediaSource;
  57. import com.google.android.exoplayer2.source.ProgressiveMediaSource;
  58. import com.google.android.exoplayer2.source.TrackGroupArray;
  59. import com.google.android.exoplayer2.source.ads.AdsLoader;
  60. import com.google.android.exoplayer2.source.ads.AdsMediaSource;
  61. import com.google.android.exoplayer2.source.dash.DashMediaSource;
  62. import com.google.android.exoplayer2.source.hls.HlsMediaSource;
  63. import com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource;
  64. import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection;
  65. import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
  66. import com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedTrackInfo;
  67. import com.google.android.exoplayer2.trackselection.RandomTrackSelection;
  68. import com.google.android.exoplayer2.trackselection.TrackSelection;
  69. import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
  70. import com.google.android.exoplayer2.ui.DebugTextViewHelper;
  71. import com.google.android.exoplayer2.ui.PlayerControlView;
  72. import com.google.android.exoplayer2.ui.PlayerView;
  73. import com.google.android.exoplayer2.ui.spherical.SphericalSurfaceView;
  74. import com.google.android.exoplayer2.upstream.DataSource;
  75. import com.google.android.exoplayer2.upstream.DataSpec;
  76. import com.google.android.exoplayer2.upstream.HttpDataSource;
  77. import com.google.android.exoplayer2.upstream.ResolvingDataSource;
  78. import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
  79. import com.google.android.exoplayer2.util.ErrorMessageProvider;
  80. import com.google.android.exoplayer2.util.EventLogger;
  81. import com.google.android.exoplayer2.util.Log;
  82. import com.google.android.exoplayer2.util.Util;
  83. import java.io.File;
  84. import java.io.FileInputStream;
  85. import java.io.FileNotFoundException;
  86. import java.io.IOException;
  87. import java.io.RandomAccessFile;
  88. import java.lang.reflect.Constructor;
  89. import java.net.CookieHandler;
  90. import java.net.CookieManager;
  91. import java.net.CookiePolicy;
  92. import java.util.UUID;
  93. import org.apache.commons.io.input.CountingInputStream;
  94.  
  95. /**
  96. * An activity that plays media using {@link SimpleExoPlayer}.
  97. */
  98. public class PlayerActivity extends AppCompatActivity
  99. implements OnClickListener, PlaybackPreparer, PlayerControlView.VisibilityListener {
  100.  
  101. public static final String DRM_SCHEME_EXTRA = "drm_scheme";
  102. public static final String DRM_LICENSE_URL_EXTRA = "drm_license_url";
  103. public static final String DRM_KEY_REQUEST_PROPERTIES_EXTRA = "drm_key_request_properties";
  104. public static final String DRM_MULTI_SESSION_EXTRA = "drm_multi_session";
  105. public static final String PREFER_EXTENSION_DECODERS_EXTRA = "prefer_extension_decoders";
  106.  
  107. public static final String ACTION_VIEW = "com.google.android.exoplayer.demo.action.VIEW";
  108. public static final String EXTENSION_EXTRA = "extension";
  109.  
  110. public static final String ACTION_VIEW_LIST =
  111. "com.google.android.exoplayer.demo.action.VIEW_LIST";
  112. public static final String URI_LIST_EXTRA = "uri_list";
  113. public static final String EXTENSION_LIST_EXTRA = "extension_list";
  114.  
  115. public static final String AD_TAG_URI_EXTRA = "ad_tag_uri";
  116.  
  117. public static final String ABR_ALGORITHM_EXTRA = "abr_algorithm";
  118. public static final String ABR_ALGORITHM_DEFAULT = "default";
  119. public static final String ABR_ALGORITHM_RANDOM = "random";
  120.  
  121. public static final String SPHERICAL_STEREO_MODE_EXTRA = "spherical_stereo_mode";
  122. public static final String SPHERICAL_STEREO_MODE_MONO = "mono";
  123. public static final String SPHERICAL_STEREO_MODE_TOP_BOTTOM = "top_bottom";
  124. public static final String SPHERICAL_STEREO_MODE_LEFT_RIGHT = "left_right";
  125.  
  126. // For backwards compatibility only.
  127. private static final String DRM_SCHEME_UUID_EXTRA = "drm_scheme_uuid";
  128.  
  129. // Saved instance state keys.
  130. private static final String KEY_TRACK_SELECTOR_PARAMETERS = "track_selector_parameters";
  131. private static final String KEY_WINDOW = "window";
  132. private static final String KEY_POSITION = "position";
  133. private static final String KEY_AUTO_PLAY = "auto_play";
  134.  
  135. private static final CookieManager DEFAULT_COOKIE_MANAGER;
  136.  
  137. static {
  138. DEFAULT_COOKIE_MANAGER = new CookieManager();
  139. DEFAULT_COOKIE_MANAGER.setCookiePolicy(CookiePolicy.ACCEPT_ORIGINAL_SERVER);
  140. }
  141.  
  142. private PlayerView playerView;
  143. private LinearLayout debugRootView;
  144. private Button selectTracksButton;
  145. private TextView debugTextView;
  146. private boolean isShowingTrackSelectionDialog;
  147.  
  148. private DataSource.Factory dataSourceFactory;
  149. private SimpleExoPlayer player;
  150. private FrameworkMediaDrm mediaDrm;
  151. private MediaSource mediaSource;
  152. private DefaultTrackSelector trackSelector;
  153. private DefaultTrackSelector.Parameters trackSelectorParameters;
  154. private DebugTextViewHelper debugViewHelper;
  155. private TrackGroupArray lastSeenTrackGroupArray;
  156.  
  157. private boolean startAutoPlay;
  158. private int startWindow;
  159. private long startPosition;
  160.  
  161. // Fields used only for ad playback. The ads loader is loaded via reflection.
  162.  
  163. private AdsLoader adsLoader;
  164. private Uri loadedAdTagUri;
  165.  
  166. // Activity lifecycle
  167.  
  168. @Override
  169. public void onCreate(Bundle savedInstanceState) {
  170. String sphericalStereoMode = getIntent().getStringExtra(SPHERICAL_STEREO_MODE_EXTRA);
  171. if (sphericalStereoMode != null) {
  172. setTheme(R.style.PlayerTheme_Spherical);
  173. }
  174. super.onCreate(savedInstanceState);
  175. dataSourceFactory = buildDataSourceFactory();
  176. if (CookieHandler.getDefault() != DEFAULT_COOKIE_MANAGER) {
  177. CookieHandler.setDefault(DEFAULT_COOKIE_MANAGER);
  178. }
  179.  
  180. setContentView(R.layout.player_activity);
  181. debugRootView = findViewById(R.id.controls_root);
  182. debugTextView = findViewById(R.id.debug_text_view);
  183. selectTracksButton = findViewById(R.id.select_tracks_button);
  184. selectTracksButton.setOnClickListener(this);
  185.  
  186. playerView = findViewById(R.id.player_view);
  187. playerView.setControllerVisibilityListener(this);
  188. playerView.setErrorMessageProvider(new PlayerErrorMessageProvider());
  189. playerView.requestFocus();
  190. if (sphericalStereoMode != null) {
  191. int stereoMode;
  192. if (SPHERICAL_STEREO_MODE_MONO.equals(sphericalStereoMode)) {
  193. stereoMode = C.STEREO_MODE_MONO;
  194. } else if (SPHERICAL_STEREO_MODE_TOP_BOTTOM.equals(sphericalStereoMode)) {
  195. stereoMode = C.STEREO_MODE_TOP_BOTTOM;
  196. } else if (SPHERICAL_STEREO_MODE_LEFT_RIGHT.equals(sphericalStereoMode)) {
  197. stereoMode = C.STEREO_MODE_LEFT_RIGHT;
  198. } else {
  199. showToast(R.string.error_unrecognized_stereo_mode);
  200. finish();
  201. return;
  202. }
  203. ((SphericalSurfaceView) playerView.getVideoSurfaceView()).setDefaultStereoMode(stereoMode);
  204. }
  205.  
  206. if (savedInstanceState != null) {
  207. trackSelectorParameters = savedInstanceState.getParcelable(KEY_TRACK_SELECTOR_PARAMETERS);
  208. startAutoPlay = savedInstanceState.getBoolean(KEY_AUTO_PLAY);
  209. startWindow = savedInstanceState.getInt(KEY_WINDOW);
  210. startPosition = savedInstanceState.getLong(KEY_POSITION);
  211. } else {
  212. trackSelectorParameters = new DefaultTrackSelector.ParametersBuilder().build();
  213. clearStartPosition();
  214. }
  215. }
  216.  
  217. @Override
  218. public void onNewIntent(Intent intent) {
  219. super.onNewIntent(intent);
  220. releasePlayer();
  221. releaseAdsLoader();
  222. clearStartPosition();
  223. setIntent(intent);
  224. }
  225.  
  226. @Override
  227. public void onStart() {
  228. super.onStart();
  229. if (Util.SDK_INT > 23) {
  230. initializePlayer();
  231. if (playerView != null) {
  232. playerView.onResume();
  233. }
  234. }
  235. }
  236.  
  237. @Override
  238. public void onResume() {
  239. super.onResume();
  240. if (Util.SDK_INT <= 23 || player == null) {
  241. initializePlayer();
  242. if (playerView != null) {
  243. playerView.onResume();
  244. }
  245. }
  246. }
  247.  
  248. @Override
  249. public void onPause() {
  250. super.onPause();
  251. if (Util.SDK_INT <= 23) {
  252. if (playerView != null) {
  253. playerView.onPause();
  254. }
  255. releasePlayer();
  256. }
  257. }
  258.  
  259. @Override
  260. public void onStop() {
  261. super.onStop();
  262. if (Util.SDK_INT > 23) {
  263. if (playerView != null) {
  264. playerView.onPause();
  265. }
  266. releasePlayer();
  267. }
  268. }
  269.  
  270. @Override
  271. public void onDestroy() {
  272. super.onDestroy();
  273. releaseAdsLoader();
  274. }
  275.  
  276. @Override
  277. public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
  278. @NonNull int[] grantResults) {
  279. if (grantResults.length == 0) {
  280. // Empty results are triggered if a permission is requested while another request was already
  281. // pending and can be safely ignored in this case.
  282. return;
  283. }
  284. if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
  285. initializePlayer();
  286. } else {
  287. showToast(R.string.storage_permission_denied);
  288. finish();
  289. }
  290. }
  291.  
  292. @Override
  293. public void onSaveInstanceState(Bundle outState) {
  294. super.onSaveInstanceState(outState);
  295. updateTrackSelectorParameters();
  296. updateStartPosition();
  297. outState.putParcelable(KEY_TRACK_SELECTOR_PARAMETERS, trackSelectorParameters);
  298. outState.putBoolean(KEY_AUTO_PLAY, startAutoPlay);
  299. outState.putInt(KEY_WINDOW, startWindow);
  300. outState.putLong(KEY_POSITION, startPosition);
  301. }
  302.  
  303. // Activity input
  304.  
  305. @Override
  306. public boolean dispatchKeyEvent(KeyEvent event) {
  307. // See whether the player view wants to handle media or DPAD keys events.
  308. return playerView.dispatchKeyEvent(event) || super.dispatchKeyEvent(event);
  309. }
  310.  
  311. // OnClickListener methods
  312.  
  313. @Override
  314. public void onClick(View view) {
  315. if (view == selectTracksButton
  316. && !isShowingTrackSelectionDialog
  317. && TrackSelectionDialog.willHaveContent(trackSelector)) {
  318. isShowingTrackSelectionDialog = true;
  319. TrackSelectionDialog trackSelectionDialog =
  320. TrackSelectionDialog.createForTrackSelector(
  321. trackSelector,
  322. /* onDismissListener= */ dismissedDialog -> isShowingTrackSelectionDialog = false);
  323. trackSelectionDialog.show(getSupportFragmentManager(), /* tag= */ null);
  324. }
  325. }
  326.  
  327. // PlaybackControlView.PlaybackPreparer implementation
  328.  
  329. @Override
  330. public void preparePlayback() {
  331. player.retry();
  332. }
  333.  
  334. // PlaybackControlView.VisibilityListener implementation
  335.  
  336. @Override
  337. public void onVisibilityChange(int visibility) {
  338. debugRootView.setVisibility(visibility);
  339. }
  340.  
  341. // Internal methods
  342.  
  343. private void initializePlayer() {
  344. if (player == null) {
  345. Intent intent = getIntent();
  346. String action = intent.getAction();
  347. Uri[] uris;
  348. String[] extensions;
  349. if (ACTION_VIEW.equals(action)) {
  350. uris = new Uri[]{intent.getData()};
  351. extensions = new String[]{intent.getStringExtra(EXTENSION_EXTRA)};
  352. } else if (ACTION_VIEW_LIST.equals(action)) {
  353. String[] uriStrings = intent.getStringArrayExtra(URI_LIST_EXTRA);
  354. uris = new Uri[uriStrings.length];
  355. for (int i = 0; i < uriStrings.length; i++) {
  356. uris[i] = Uri.parse(uriStrings[i]);
  357. }
  358. extensions = intent.getStringArrayExtra(EXTENSION_LIST_EXTRA);
  359. if (extensions == null) {
  360. extensions = new String[uriStrings.length];
  361. }
  362. } else {
  363. showToast(getString(R.string.unexpected_intent_action, action));
  364. finish();
  365. return;
  366. }
  367. if (!Util.checkCleartextTrafficPermitted(uris)) {
  368. showToast(R.string.error_cleartext_not_permitted);
  369. return;
  370. }
  371. if (Util.maybeRequestReadExternalStoragePermission(/* activity= */ this, uris)) {
  372. // The player will be reinitialized if the permission is granted.
  373. return;
  374. }
  375.  
  376. DefaultDrmSessionManager<FrameworkMediaCrypto> drmSessionManager = null;
  377. if (intent.hasExtra(DRM_SCHEME_EXTRA) || intent.hasExtra(DRM_SCHEME_UUID_EXTRA)) {
  378. String drmLicenseUrl = intent.getStringExtra(DRM_LICENSE_URL_EXTRA);
  379. String[] keyRequestPropertiesArray =
  380. intent.getStringArrayExtra(DRM_KEY_REQUEST_PROPERTIES_EXTRA);
  381. boolean multiSession = intent.getBooleanExtra(DRM_MULTI_SESSION_EXTRA, false);
  382. int errorStringId = R.string.error_drm_unknown;
  383. if (Util.SDK_INT < 18) {
  384. errorStringId = R.string.error_drm_not_supported;
  385. } else {
  386. try {
  387. String drmSchemeExtra = intent.hasExtra(DRM_SCHEME_EXTRA) ? DRM_SCHEME_EXTRA
  388. : DRM_SCHEME_UUID_EXTRA;
  389. UUID drmSchemeUuid = Util.getDrmUuid(intent.getStringExtra(drmSchemeExtra));
  390. if (drmSchemeUuid == null) {
  391. errorStringId = R.string.error_drm_unsupported_scheme;
  392. } else {
  393. drmSessionManager =
  394. buildDrmSessionManagerV18(
  395. drmSchemeUuid, drmLicenseUrl, keyRequestPropertiesArray, multiSession);
  396. }
  397. } catch (UnsupportedDrmException e) {
  398. errorStringId = e.reason == UnsupportedDrmException.REASON_UNSUPPORTED_SCHEME
  399. ? R.string.error_drm_unsupported_scheme : R.string.error_drm_unknown;
  400. }
  401. }
  402. if (drmSessionManager == null) {
  403. showToast(errorStringId);
  404. finish();
  405. return;
  406. }
  407. }
  408.  
  409. TrackSelection.Factory trackSelectionFactory;
  410. String abrAlgorithm = intent.getStringExtra(ABR_ALGORITHM_EXTRA);
  411. if (abrAlgorithm == null || ABR_ALGORITHM_DEFAULT.equals(abrAlgorithm)) {
  412. trackSelectionFactory = new AdaptiveTrackSelection.Factory();
  413. } else if (ABR_ALGORITHM_RANDOM.equals(abrAlgorithm)) {
  414. trackSelectionFactory = new RandomTrackSelection.Factory();
  415. } else {
  416. showToast(R.string.error_unrecognized_abr_algorithm);
  417. finish();
  418. return;
  419. }
  420.  
  421. boolean preferExtensionDecoders =
  422. intent.getBooleanExtra(PREFER_EXTENSION_DECODERS_EXTRA, false);
  423. RenderersFactory renderersFactory =
  424. ((DemoApplication) getApplication()).buildRenderersFactory(preferExtensionDecoders);
  425.  
  426. trackSelector = new DefaultTrackSelector(trackSelectionFactory);
  427. trackSelector.setParameters(trackSelectorParameters);
  428. lastSeenTrackGroupArray = null;
  429.  
  430. player = ExoPlayerFactory
  431. .newSimpleInstance(this, renderersFactory, trackSelector, drmSessionManager);
  432. player.addListener(new PlayerEventListener());
  433. player.setPlayWhenReady(startAutoPlay);
  434. player.addAnalyticsListener(new EventLogger(trackSelector));
  435.  
  436. Uri uri = Uri
  437. .fromFile(new File(Environment.getExternalStorageDirectory() + "/dance.mp5"));
  438.  
  439. //.fromFile(new File(Environment.getExternalStorageDirectory() + "/dance.mp5"));
  440. /*DataSpec dataSpec = new DataSpec(uri);
  441. final MyDataSource inputStreamDataSource = new MyDataSource(this, dataSpec);*/
  442. /*try {
  443. inputStreamDataSource.open(dataSpec);
  444. } catch (IOException e) {
  445. e.printStackTrace();
  446. }*/
  447.  
  448. //Mp4Extractor
  449.  
  450. //DataSource.Factory factory = () -> inputStreamDataSource;
  451. //mediaSource = new ProgressiveMediaSource.Factory(factory).createMediaSource(uri);
  452. //dataSourceFactory = buildDataSourceFactory();
  453. //mediaSource = new ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "/jellies.mp4")));
  454. //mediaSource = new ExtractorMediaSource(Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "/test.mp5")),factory, new DefaultExtractorsFactory(), null, null);
  455.  
  456. mediaSource = createLeafMediaSource(uri, null, null);
  457. /*final FileDataSource fileDataSource = new FileDataSource();
  458. try {
  459. fileDataSource.open(dataSpec);
  460. } catch (FileDataSource.FileDataSourceException e) {
  461. e.printStackTrace();
  462. }
  463. DataSource.Factory factory = () -> fileDataSource;
  464.  
  465. mediaSource = new ProgressiveMediaSource.Factory(factory).createMediaSource(uri);*/
  466.  
  467. //TODO
  468. /*long offset = 16;
  469. DataSpec dataSpec1 = new DataSpec(
  470. dataSpec.uri,
  471. dataSpec.httpMethod,
  472. dataSpec.httpBody,
  473. dataSpec.absoluteStreamPosition + offset,
  474. dataSpec.position + offset,
  475. dataSpec.length,
  476. dataSpec.key,
  477. dataSpec.flags);
  478.  
  479. ResolvingDataSource.Resolver resolver = dataSpec2 -> dataSpec1;
  480.  
  481. mediaSource = new ProgressiveMediaSource.Factory(
  482. new ResolvingDataSource.Factory(dataSourceFactory, resolver)).createMediaSource(uri);*/
  483. //TODO
  484.  
  485. //ResolvingDataSource dataSource = new ResolvingDataSource.Factory(dataSourceFactory, resolver).createDataSource();
  486.  
  487. //ResolvingDataSource.Factory(new ResolvingDataSource1(dataSourceFactory, resolver));
  488. playerView.setPlayer(player);
  489. playerView.setPlaybackPreparer(this);
  490. debugViewHelper = new DebugTextViewHelper(player, debugTextView);
  491. debugViewHelper.start();
  492.  
  493. }
  494. boolean haveStartPosition = startWindow != C.INDEX_UNSET;
  495. if (haveStartPosition) {
  496. player.seekTo(startWindow, startPosition);
  497. }
  498. //player.prepare(mediaSource, !haveStartPosition, false);
  499. player.prepare(mediaSource);
  500. updateButtonVisibility();
  501. }
  502.  
  503. private MediaSource createLeafMediaSource(
  504. Uri uri, String extension, DrmSessionManager<ExoMediaCrypto> drmSessionManager) {
  505. @ContentType int type = Util.inferContentType(uri, extension);
  506. switch (type) {
  507. case C.TYPE_DASH:
  508. return new DashMediaSource.Factory(dataSourceFactory)
  509. //.setDrmSessionManager(drmSessionManager)
  510. .createMediaSource(uri);
  511. case C.TYPE_SS:
  512. return new SsMediaSource.Factory(dataSourceFactory)
  513. //.setDrmSessionManager(drmSessionManager)
  514. .createMediaSource(uri);
  515. case C.TYPE_HLS:
  516. return new HlsMediaSource.Factory(dataSourceFactory)
  517. //.setDrmSessionManager(drmSessionManager)
  518. .createMediaSource(uri);
  519. case C.TYPE_OTHER:
  520. Log.d("createLeafMediaSource", "other");
  521. // return new ProgressiveMediaSource.Factory(dataSourceFactory)
  522. //return createResolverMediaSourceFactory()
  523. return createResolverMediaSourceFactory1()
  524. //.setDrmSessionManager(drmSessionManager)
  525. .createMediaSource(uri);
  526. default:
  527. throw new IllegalStateException("Unsupported type: " + type);
  528. }
  529. }
  530.  
  531. private ProgressiveMediaSource.Factory createResolverMediaSourceFactory() {
  532. return new ProgressiveMediaSource.Factory(
  533. new ResolvingDataSource.Factory(dataSourceFactory, new MyResolver(348, 348328149)));
  534. //new ResolvingDataSource.Factory(dataSourceFactory, new MyResolver(16, 1692377)));
  535. }
  536.  
  537. private ProgressiveMediaSource.Factory createResolverMediaSourceFactory1() {
  538. final MyDataSource inputStreamDataSource = new MyDataSource(this);
  539. DataSource.Factory factory = () -> inputStreamDataSource;
  540.  
  541. return new ProgressiveMediaSource.Factory(
  542. new ResolvingDataSource.Factory(factory, new MyResolver(348, 348328149)));
  543. //new ResolvingDataSource.Factory(dataSourceFactory, new MyResolver(16, 1692377)));
  544. }
  545.  
  546. private class MyResolver implements ResolvingDataSource.Resolver {
  547.  
  548. private long offset;
  549. private long length;
  550.  
  551. public MyResolver(long offset, long length) {
  552. this.offset = offset;
  553. this.length = length;
  554. }
  555.  
  556. @Override
  557. public DataSpec resolveDataSpec(DataSpec dataSpec) {
  558.  
  559. return new DataSpec(
  560. dataSpec.uri,
  561. dataSpec.httpMethod,
  562. dataSpec.httpBody,
  563. dataSpec.absoluteStreamPosition + offset,
  564. dataSpec.position + offset,
  565. length,
  566. dataSpec.key,
  567. dataSpec.flags);
  568. }
  569.  
  570. @Override
  571. public Uri resolveReportedUri(Uri uri) {
  572. return uri;
  573. }
  574. }
  575.  
  576. public byte[] XOR(byte[] incomeByteArray, byte[] key) {
  577. byte[] result = new byte[incomeByteArray.length];
  578. int j = 0;
  579.  
  580. for (int i = 0; i < incomeByteArray.length; i++) {
  581. result[i] = (byte) (incomeByteArray[i] ^ key[j]);
  582. j++;
  583. if (j == key.length) {
  584. j = 0;
  585. }
  586. }
  587. return result;
  588. }
  589.  
  590. private MediaSource buildMediaSource(Uri uri) {
  591. return buildMediaSource(uri, null);
  592. }
  593.  
  594. private MediaSource buildMediaSource(Uri uri, @Nullable String overrideExtension) {
  595. DownloadRequest downloadRequest =
  596. ((DemoApplication) getApplication()).getDownloadTracker().getDownloadRequest(uri);
  597. if (downloadRequest != null) {
  598. return DownloadHelper.createMediaSource(downloadRequest, dataSourceFactory);
  599. }
  600. @ContentType int type = Util.inferContentType(uri, overrideExtension);
  601. switch (type) {
  602. case C.TYPE_DASH:
  603. return new DashMediaSource.Factory(dataSourceFactory).createMediaSource(uri);
  604. case C.TYPE_SS:
  605. return new SsMediaSource.Factory(dataSourceFactory).createMediaSource(uri);
  606. case C.TYPE_HLS:
  607. return new HlsMediaSource.Factory(dataSourceFactory).createMediaSource(uri);
  608. case C.TYPE_OTHER:
  609. return new ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(uri);
  610. default:
  611. throw new IllegalStateException("Unsupported type: " + type);
  612. }
  613. }
  614.  
  615. private DefaultDrmSessionManager<FrameworkMediaCrypto> buildDrmSessionManagerV18(
  616. UUID uuid, String licenseUrl, String[] keyRequestPropertiesArray, boolean multiSession)
  617. throws UnsupportedDrmException {
  618. HttpDataSource.Factory licenseDataSourceFactory =
  619. ((DemoApplication) getApplication()).buildHttpDataSourceFactory();
  620. HttpMediaDrmCallback drmCallback =
  621. new HttpMediaDrmCallback(licenseUrl, licenseDataSourceFactory);
  622. if (keyRequestPropertiesArray != null) {
  623. for (int i = 0; i < keyRequestPropertiesArray.length - 1; i += 2) {
  624. drmCallback.setKeyRequestProperty(keyRequestPropertiesArray[i],
  625. keyRequestPropertiesArray[i + 1]);
  626. }
  627. }
  628. releaseMediaDrm();
  629. mediaDrm = FrameworkMediaDrm.newInstance(uuid);
  630. return new DefaultDrmSessionManager<>(uuid, mediaDrm, drmCallback, null, multiSession);
  631. }
  632.  
  633. private void releasePlayer() {
  634. if (player != null) {
  635. updateTrackSelectorParameters();
  636. updateStartPosition();
  637. debugViewHelper.stop();
  638. debugViewHelper = null;
  639. player.release();
  640. player = null;
  641. mediaSource = null;
  642. trackSelector = null;
  643. }
  644. if (adsLoader != null) {
  645. adsLoader.setPlayer(null);
  646. }
  647. releaseMediaDrm();
  648. }
  649.  
  650. private void releaseMediaDrm() {
  651. if (mediaDrm != null) {
  652. mediaDrm.release();
  653. mediaDrm = null;
  654. }
  655. }
  656.  
  657. private void releaseAdsLoader() {
  658. if (adsLoader != null) {
  659. adsLoader.release();
  660. adsLoader = null;
  661. loadedAdTagUri = null;
  662. playerView.getOverlayFrameLayout().removeAllViews();
  663. }
  664. }
  665.  
  666. private void updateTrackSelectorParameters() {
  667. if (trackSelector != null) {
  668. trackSelectorParameters = trackSelector.getParameters();
  669. }
  670. }
  671.  
  672. private void updateStartPosition() {
  673. if (player != null) {
  674. startAutoPlay = player.getPlayWhenReady();
  675. startWindow = player.getCurrentWindowIndex();
  676. startPosition = Math.max(0, player.getContentPosition());
  677. }
  678. }
  679.  
  680. private void clearStartPosition() {
  681. startAutoPlay = true;
  682. startWindow = C.INDEX_UNSET;
  683. startPosition = C.TIME_UNSET;
  684. }
  685.  
  686. /**
  687. * Returns a new DataSource factory.
  688. */
  689. private DataSource.Factory buildDataSourceFactory() {
  690. return ((DemoApplication) getApplication()).buildDataSourceFactory();
  691. }
  692.  
  693. /**
  694. * Returns an ads media source, reusing the ads loader if one exists.
  695. */
  696. private @Nullable
  697. MediaSource createAdsMediaSource(MediaSource mediaSource, Uri adTagUri) {
  698. // Load the extension source using reflection so the demo app doesn't have to depend on it.
  699. // The ads loader is reused for multiple playbacks, so that ad playback can resume.
  700. try {
  701. Class<?> loaderClass = Class.forName("com.google.android.exoplayer2.ext.ima.ImaAdsLoader");
  702. if (adsLoader == null) {
  703. // Full class names used so the LINT.IfChange rule triggers should any of the classes move.
  704. // LINT.IfChange
  705. Constructor<? extends AdsLoader> loaderConstructor =
  706. loaderClass
  707. .asSubclass(AdsLoader.class)
  708. .getConstructor(android.content.Context.class, android.net.Uri.class);
  709. // LINT.ThenChange(../../../../../../../../proguard-rules.txt)
  710. adsLoader = loaderConstructor.newInstance(this, adTagUri);
  711. }
  712. adsLoader.setPlayer(player);
  713. AdsMediaSource.MediaSourceFactory adMediaSourceFactory =
  714. new AdsMediaSource.MediaSourceFactory() {
  715. @Override
  716. public MediaSource createMediaSource(Uri uri) {
  717. return PlayerActivity.this.buildMediaSource(uri);
  718. }
  719.  
  720. @Override
  721. public int[] getSupportedTypes() {
  722. return new int[]{C.TYPE_DASH, C.TYPE_SS, C.TYPE_HLS, C.TYPE_OTHER};
  723. }
  724. };
  725. return new AdsMediaSource(mediaSource, adMediaSourceFactory, adsLoader, playerView);
  726. } catch (ClassNotFoundException e) {
  727. // IMA extension not loaded.
  728. return null;
  729. } catch (Exception e) {
  730. throw new RuntimeException(e);
  731. }
  732. }
  733.  
  734. // User controls
  735.  
  736. private void updateButtonVisibility() {
  737. selectTracksButton.setEnabled(
  738. player != null && TrackSelectionDialog.willHaveContent(trackSelector));
  739. }
  740.  
  741. private void showControls() {
  742. debugRootView.setVisibility(View.VISIBLE);
  743. }
  744.  
  745. private void showToast(int messageId) {
  746. showToast(getString(messageId));
  747. }
  748.  
  749. private void showToast(String message) {
  750. Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
  751. }
  752.  
  753. private static boolean isBehindLiveWindow(ExoPlaybackException e) {
  754. if (e.type != ExoPlaybackException.TYPE_SOURCE) {
  755. return false;
  756. }
  757. Throwable cause = e.getSourceException();
  758. while (cause != null) {
  759. if (cause instanceof BehindLiveWindowException) {
  760. return true;
  761. }
  762. cause = cause.getCause();
  763. }
  764. return false;
  765. }
  766.  
  767. private class PlayerEventListener implements Player.EventListener {
  768.  
  769. @Override
  770. public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
  771. if (playbackState == Player.STATE_ENDED) {
  772. showControls();
  773. }
  774. updateButtonVisibility();
  775. }
  776.  
  777. @Override
  778. public void onPlayerError(ExoPlaybackException e) {
  779. if (isBehindLiveWindow(e)) {
  780. clearStartPosition();
  781. initializePlayer();
  782. } else {
  783. updateButtonVisibility();
  784. showControls();
  785. }
  786. }
  787.  
  788. @Override
  789. @SuppressWarnings("ReferenceEquality")
  790. public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
  791. updateButtonVisibility();
  792. if (trackGroups != lastSeenTrackGroupArray) {
  793. MappedTrackInfo mappedTrackInfo = trackSelector.getCurrentMappedTrackInfo();
  794. if (mappedTrackInfo != null) {
  795. if (mappedTrackInfo.getTypeSupport(C.TRACK_TYPE_VIDEO)
  796. == MappedTrackInfo.RENDERER_SUPPORT_UNSUPPORTED_TRACKS) {
  797. showToast(R.string.error_unsupported_video);
  798. }
  799. if (mappedTrackInfo.getTypeSupport(C.TRACK_TYPE_AUDIO)
  800. == MappedTrackInfo.RENDERER_SUPPORT_UNSUPPORTED_TRACKS) {
  801. showToast(R.string.error_unsupported_audio);
  802. }
  803. }
  804. lastSeenTrackGroupArray = trackGroups;
  805. }
  806. }
  807. }
  808.  
  809. private class PlayerErrorMessageProvider implements ErrorMessageProvider<ExoPlaybackException> {
  810.  
  811. @Override
  812. public Pair<Integer, String> getErrorMessage(ExoPlaybackException e) {
  813. String errorString = getString(R.string.error_generic);
  814. if (e.type == ExoPlaybackException.TYPE_RENDERER) {
  815. Exception cause = e.getRendererException();
  816. if (cause instanceof DecoderInitializationException) {
  817. // Special case for decoder initialization failures.
  818. DecoderInitializationException decoderInitializationException =
  819. (DecoderInitializationException) cause;
  820. if (decoderInitializationException.decoderName == null) {
  821. if (decoderInitializationException.getCause() instanceof DecoderQueryException) {
  822. errorString = getString(R.string.error_querying_decoders);
  823. } else if (decoderInitializationException.secureDecoderRequired) {
  824. errorString =
  825. getString(
  826. R.string.error_no_secure_decoder, decoderInitializationException.mimeType);
  827. } else {
  828. errorString =
  829. getString(R.string.error_no_decoder, decoderInitializationException.mimeType);
  830. }
  831. } else {
  832. errorString =
  833. getString(
  834. R.string.error_instantiating_decoder,
  835. decoderInitializationException.decoderName);
  836. }
  837. }
  838. }
  839. return Pair.create(0, errorString);
  840. }
  841. }
  842.  
  843. }
RAW Paste Data