Guest User

Untitled

a guest
Jun 23rd, 2017
233
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 109.79 KB | None | 0 0
  1. /*
  2.  * Copyright (C) 2007 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.nexstreaming.app.apis;
  17.  
  18. import android.annotation.SuppressLint;
  19. import android.app.AlertDialog;
  20. import android.app.KeyguardManager;
  21. import android.app.UiModeManager;
  22. import android.content.BroadcastReceiver;
  23. import android.content.ContentResolver;
  24. import android.content.Context;
  25. import android.content.DialogInterface;
  26. import android.content.Intent;
  27. import android.content.IntentFilter;
  28. import android.content.pm.ActivityInfo;
  29. import android.content.res.Configuration;
  30. import android.database.Cursor;
  31. import android.graphics.Bitmap;
  32. import android.graphics.Bitmap.Config;
  33. import android.graphics.BitmapFactory;
  34. import android.graphics.Color;
  35. import android.graphics.Matrix;
  36. import android.graphics.PixelFormat;
  37. import android.graphics.Point;
  38. import android.graphics.Rect;
  39. import android.media.AudioManager;
  40. import android.net.Uri;
  41. import android.os.Build;
  42. import android.os.Bundle;
  43. import android.os.CountDownTimer;
  44. import android.os.Environment;
  45. import android.os.Handler;
  46. import android.provider.MediaStore;
  47. import android.support.v7.app.ActionBar;
  48. import android.support.v7.app.AppCompatActivity;
  49. import android.support.v7.widget.Toolbar;
  50. import android.text.TextUtils;
  51. import android.util.Base64;
  52. import android.util.Log;
  53. import android.view.Gravity;
  54. import android.view.KeyEvent;
  55. import android.view.Menu;
  56. import android.view.MenuInflater;
  57. import android.view.MenuItem;
  58. import android.view.View;
  59. import android.view.View.OnClickListener;
  60. import android.view.ViewGroup;
  61. import android.view.Window;
  62. import android.view.WindowManager;
  63. import android.widget.CheckBox;
  64. import android.widget.CompoundButton;
  65. import android.widget.ImageView;
  66. import android.widget.RelativeLayout;
  67. import android.widget.ScrollView;
  68. import android.widget.SeekBar;
  69. import android.widget.TextView;
  70. import android.widget.Toast;
  71.  
  72. import com.google.ads.interactivemedia.v3.api.AdDisplayContainer;
  73. import com.google.ads.interactivemedia.v3.api.AdErrorEvent;
  74. import com.google.ads.interactivemedia.v3.api.AdEvent;
  75. import com.google.ads.interactivemedia.v3.api.AdsLoader;
  76. import com.google.ads.interactivemedia.v3.api.AdsManager;
  77. import com.google.ads.interactivemedia.v3.api.AdsManagerLoadedEvent;
  78. import com.google.ads.interactivemedia.v3.api.AdsRequest;
  79. import com.google.ads.interactivemedia.v3.api.ImaSdkFactory;
  80. import com.google.ads.interactivemedia.v3.api.player.ContentProgressProvider;
  81. import com.google.ads.interactivemedia.v3.api.player.VideoProgressUpdate;
  82. import com.nexstreaming.app.apis.BandwidthDialog.IBandwidthListener;
  83. import com.nexstreaming.app.apis.DolbyDialog.IDolbyListener;
  84. import com.nexstreaming.app.apis.MultiStreamDialog.IMultiStreamListener;
  85. import com.nexstreaming.app.apis.MultiStreamDialog.MULTISTREAM_BUTTON;
  86. import com.nexstreaming.app.apis.VolumeDialog.IVolumeListener;
  87. import com.nexstreaming.app.apis.VolumeDialog.VOLUME_BUTTON;
  88. import com.nexstreaming.app.dialog.NexContentInfoDialog;
  89. import com.nexstreaming.app.nexplayersample.R;
  90. import com.nexstreaming.app.nxb.info.NxbInfo;
  91. import com.nexstreaming.app.util.FastPlayUtil;
  92. import com.nexstreaming.app.util.NetworkBroadcastReceiver;
  93. import com.nexstreaming.app.util.NetworkUtils;
  94. import com.nexstreaming.app.util.NexFileIO;
  95. import com.nexstreaming.app.util.PlayListUtils;
  96. import com.nexstreaming.app.widget.NexImageButton;
  97. import com.nexstreaming.nexplayerengine.NexABRController;
  98. import com.nexstreaming.nexplayerengine.NexALFactory;
  99. import com.nexstreaming.nexplayerengine.NexCaptionPainter;
  100. import com.nexstreaming.nexplayerengine.NexCaptionSetting;
  101. import com.nexstreaming.nexplayerengine.NexClosedCaption;
  102. import com.nexstreaming.nexplayerengine.NexClosedCaption.CaptionColor;
  103. import com.nexstreaming.nexplayerengine.NexContentInformation;
  104. import com.nexstreaming.nexplayerengine.NexCustomAttribInformation;
  105. import com.nexstreaming.nexplayerengine.NexEventReceiver;
  106. import com.nexstreaming.nexplayerengine.NexID3TagInformation;
  107. import com.nexstreaming.nexplayerengine.NexID3TagPicture;
  108. import com.nexstreaming.nexplayerengine.NexID3TagText;
  109. import com.nexstreaming.nexplayerengine.NexNetAddrTable;
  110. import com.nexstreaming.nexplayerengine.NexPictureTimingInfo;
  111. import com.nexstreaming.nexplayerengine.NexPlayer;
  112. import com.nexstreaming.nexplayerengine.NexPlayer.NexErrorCode;
  113. import com.nexstreaming.nexplayerengine.NexPlayer.NexProperty;
  114. import com.nexstreaming.nexplayerengine.NexStatisticsMonitor;
  115.  
  116. import com.nexstreaming.nexplayerengine.NexStoredInfoFileUtils;
  117. import com.nexstreaming.nexplayerengine.NexSurfaceTextureBinder;
  118. import com.nexstreaming.nexplayerengine.NexSurfaceTextureView;
  119. import com.nexstreaming.nexplayerengine.NexSystemInfo;
  120. import com.nexstreaming.nexplayerengine.NexVideoRenderer;
  121. import com.nexstreaming.nexplayerengine.NexVideoViewFactory;
  122. import com.npaw.youbora.plugins.nexstreaming.PluginNexStreaming;
  123. import com.npaw.youbora.youboralib.utils.YBLog;
  124. import com.utils.YouboraConfigManager;
  125.  
  126. import java.io.File;
  127. import java.nio.ByteBuffer;
  128. import java.util.ArrayList;
  129. import java.util.HashMap;
  130. import java.util.List;
  131. import java.util.Timer;
  132. import java.util.TimerTask;
  133.  
  134. import static com.nexstreaming.nexplayerengine.NexStatisticsMonitor.IStatistics;
  135. import static com.nexstreaming.nexplayerengine.NexStatisticsMonitor.STATISTICS_GENERAL;
  136.  
  137. import org.json.JSONException;
  138. import org.json.JSONObject;
  139.  
  140.  
  141.  
  142. public class NexPlayerSample extends AppCompatActivity implements NetworkBroadcastReceiver.NetworkListener{
  143.    
  144.     private static final String LOG_TAG = "NexPlayerSample";
  145.     public static final Handler mHandler = new Handler();
  146.  
  147.     private final int AUDIO_ONLY    = 1;
  148.     private final int VIDEO_ONLY    = 2;
  149.     private final int AUDIO_VIDEO   = 3;
  150.  
  151.     private static final int BANDWIDTH_KBPS = 1024;
  152.    
  153.     private static final int RESET_PLAYER_ALL = 0;
  154.     private static final int RESET_PLAYER_PROGRESS = 1;
  155.     private static final int RESET_PLAYER_BASIC = 2;
  156.    
  157.     private static final int REPLAY_MODE_NEXT = 0;
  158.     private static final int REPLAY_MODE_AGAIN = 1;
  159.     private static final int REPLAY_MODE_QUIT = 2;
  160.     private static final int REPLAY_MODE_PREVIOUS = 3;
  161.    
  162.     private static final int NEXPLAYER_PROPERTY_ENABLE_MEDIA_DRM = 215;
  163.     private static final int NEXPLAYER_PROPERTY_DATA_DUMP_SUB_PATH = 0x00070000;
  164.  
  165.     private static final int SCALE_FIT_TO_SCREEN = 0;
  166.     private static final int SCALE_ORIGINAL = 1;
  167.     private static final int SCALE_STRETCH_TO_SCREEN = 2;
  168.  
  169.     private int mScaleMode = SCALE_FIT_TO_SCREEN;
  170.    
  171.     private ArrayList<File> mFileList;
  172.     protected String mCurrentPath;
  173.     private boolean mExistFollowingContentPath;
  174.  
  175.     private String mCurrentExtraData;
  176.     private String mCurrentSubtitlePath = null;
  177.     private int mCurrentPosition = 0;
  178.     private String mTargetSubtitlePath = null;
  179.  
  180.     private NexContentInformation mContentInfo = null;
  181.     private ArrayList<NxbInfo>mNxbWholeList;
  182.    
  183.     //preference
  184.     private float mVolume = 10.0f;
  185.    
  186.     private boolean mNeedResume = false;
  187.     private boolean mIsHeadsetRemoved = false;
  188.    
  189.     private boolean mAudioInitEnd = false;
  190.  
  191.     private NexSurfaceTextureView mVideoSurfaceView;
  192.     private NexVideoViewFactory.INexVideoView mVideoView = null;
  193.     protected NexPlayer mNexPlayer;
  194.     private NexEventReceiver mEventReceiver;
  195.     private NexALFactory mNexALFactory;
  196.     private NexABRController mABRController;
  197.    
  198.     private BroadcastReceiver mBroadcastReceiver;
  199.    
  200.     //ui components
  201.     private ViewGroup mVisibilityLayout;
  202.     private ThumbnailSeekBar mSeekBar;
  203.     private ImageView mImageView;
  204.     private ImageView mThumbnailView;
  205.     private NexImageButton mPreviousButton;
  206.     private NexImageButton mRewindButton;
  207.     private NexImageButton mPlayPauseButton;
  208.     private NexImageButton mFastForwardButton;
  209.     private NexImageButton mNextButton;
  210.     private NexImageButton mGoToLiveButton;
  211.     private TextView mStatisticTextview;
  212.     private ScrollView mLyricScrollView;
  213.     private TextView mLyricView;
  214.     private TextView mErrorView;
  215.     private TextView mTrackView;
  216.  
  217.     private CaptionStyleDialog mCaptionDialog;
  218.     private int mVideoWidth = 0;
  219.     private int mVideoHeight = 0;
  220.    
  221.     // buffer info
  222.     private RelativeLayout mProgressLayout;
  223.     private TextView mProgressTextView;
  224.     private boolean mIsBuffering = false;
  225.    
  226.     // seek information
  227.     private int mProgressBase = 0;
  228.     private int mSeekPoint = -1;
  229.     private boolean mIsSeeking = false;
  230.    
  231.     //Streaming status
  232.     private boolean mIsStreaming = false;
  233.     private boolean mIsLive = false;
  234.     private boolean mIsStoreManagerInitialized = false;
  235.     private boolean mHaveToResizeVideoViewInPIPMode = false;
  236.     private boolean mHaveToStartPlayer = false;
  237.    
  238.     private boolean mIsEnginOpen = false;
  239.     //player status
  240.     private enum PLAYER_FLOW_STATE {
  241.         START_PLAY, BEGINNING_OF_COMPLETE, END_OF_COMPLETE, FINISH_ACTIVITY, BEGINNING_OF_ONERROR, END_OF_ONERROR, STATE_NONE
  242.     };
  243.     private PLAYER_FLOW_STATE mPlayerState = PLAYER_FLOW_STATE.STATE_NONE;
  244.     //Caption Render Information
  245.  
  246.     private NexCaptionPainter mCaptionPainter = null;
  247.     //private NexCaptionSetting mCaptionSettings = new NexCaptionSetting();
  248.  
  249.     private int mCEA608CaptionChannel = 1;
  250.    
  251.     private boolean mForeground = true;
  252.  
  253.     private int mExternalPDBufferDuration = 0;
  254.     private int mDownloaderState = NexPlayer.NEXDOWNLOADER_STATE_NONE;
  255.     private String mStrExternalPDFile = null;  
  256.     private long mTotalSize = 0;
  257.  
  258.     //time meta
  259.     private TextView mLyricTextView = null;
  260.     private TextView mTimedMetaTextView = null;
  261.    
  262.     CaptionStyleDialogUtil captionStyleDialogUtil = new CaptionStyleDialogUtil();
  263.    
  264.     private RelativeLayout mParentView;
  265.    
  266.     private boolean mNeedStartSeekBarTime = false;
  267.    
  268.     private PlayerSampleUtils playerSampleUtils = PlayerSampleUtils.sharedInstance();
  269.     private PlayListUtils mPlayListUtil;
  270.  
  271.     private NexPreferenceData mPrefData = null;
  272.  
  273.     private StatisticsDialog mStatisticsDialog;
  274.     private MultiStreamDialog mMultistreamDialog;
  275.     private BandwidthDialog mBandwidthDialog;
  276.     private VolumeDialog mVolumeDialog;
  277.     private DolbyDialog mDolbyDialog;
  278.     private AlertDialog mScaleDialog = null;
  279.     private CaptionDownloadDialog mCaptionDownloadDialog = null;
  280.     private TargetBandWidthDialog mTargetBandWidthDialog = null;
  281.     private CaptionLanguageDialog mCaptionLanquageDialog = null;
  282.     private SubtitleChangeDialog mSubtitleChangeDialog = null;
  283.     private NexContentInfoDialog mContentInfoDialog = null;
  284.  
  285.     private boolean mFastPlay = false;
  286.     private float   mFastPlaySpeed = 1.0f;
  287.  
  288.     private Timer mTimer = null;
  289.     private CountDownTimer clientTimeshiftTimer = null;
  290.     private String mCacheFolderPath = null;
  291.  
  292.     private int mTempVideoStreamID = NexPlayer.MEDIA_STREAM_DEFAULT_ID;
  293.  
  294.     private NexStatisticsMonitor.IStatisticsListener mStatisticsListener;
  295.     private NexStatisticsMonitor mStatisticsMonitor;
  296.  
  297.     protected Toolbar mToolbar;
  298.  
  299.     // Youbora plugin
  300.     private PluginNexStreaming youboraPlugin;
  301.  
  302.     //Google IMA
  303.     // The container for the ad's UI.
  304.     private ViewGroup mAdUiContainer;
  305.  
  306.     // Factory class for creating SDK objects.
  307.     private ImaSdkFactory mSdkFactory;
  308.  
  309.     // The AdsLoader instance exposes the requestAds method.
  310.     private AdsLoader mAdsLoader;
  311.  
  312.     // AdsManager exposes methods to control ad playback and listen to ad events.
  313.     private AdsManager mAdsManager;
  314.  
  315.     // Whether an ad is displayed.
  316.     private boolean mIsAdDisplayed;
  317.    
  318.     @SuppressLint("InlinedApi")
  319.     public void onCreate(Bundle icicle) {
  320.         mPrefData = new NexPreferenceData( getApplicationContext() );
  321.         mPrefData.loadPreferenceData();
  322.  
  323.         setPreloader();
  324.  
  325.         super.onCreate(icicle);
  326.         if( Build.VERSION.SDK_INT > Build.VERSION_CODES.FROYO ) {
  327.             setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
  328.         }
  329.         if( Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB ) {
  330.             requestWindowFeature(Window.FEATURE_NO_TITLE);
  331.         }
  332.  
  333.         mStatisticsDialog = new StatisticsDialog(this);
  334.         mMultistreamDialog = new MultiStreamDialog(this);
  335.         mBandwidthDialog = new BandwidthDialog(this);
  336.         mVolumeDialog = new VolumeDialog(this);
  337.         mDolbyDialog = new DolbyDialog(this, mDolbyDialogListener, mPrefData.mEnableDolbyPostProcessing, mPrefData.mDolbyEndPoint, mPrefData.mDolbyEnhancementGain);
  338.         mTargetBandWidthDialog = new TargetBandWidthDialog(this, new TargetBandWidthDialog.TargetBandWidthIListener() {
  339.             @Override
  340.             public void onTargetBandWidthDialogUpdated(boolean abrEnabled, int targetBandWidth, NexABRController.SegmentOption segOption, NexABRController.TargetOption targetOption) {
  341.                 mABRController.setABREnabled(abrEnabled);
  342.  
  343.                 if( !abrEnabled ) {
  344.                     NexErrorCode result = mABRController.setTargetBandWidth(targetBandWidth, segOption, targetOption);
  345.                     Log.d(LOG_TAG, "onTargetBandWidthUpdated setTargetBandWidth result : " + result);
  346.                 }
  347.             }
  348.         }, mPrefData.mEnableAudioOnlyTrack);
  349.         mCaptionLanquageDialog = new CaptionLanguageDialog(this, new CaptionLanguageDialog.Listener() {
  350.             @Override
  351.             public void onItemClicked(int position, boolean disable) {
  352.                 mNexPlayer.setCaptionLanguage(position);
  353.                 clearCaptionString();
  354.             }
  355.         });
  356.         mSubtitleChangeDialog = new SubtitleChangeDialog(this, new SubtitleChangeDialog.Listener() {
  357.             @Override
  358.             public void onSubtitleChanged(String subtitlePath) {
  359.                 Log.d(LOG_TAG, "mSubtitleChangeDialog onSubtitleChanged subtitlePath : " + subtitlePath);
  360.                 int result = mNexPlayer.changeSubtitlePath(subtitlePath);
  361.                 if( result == 0 ) {
  362.                     mTargetSubtitlePath = subtitlePath;
  363.                 } else {
  364.                     showToastMsg(getString(R.string.invalid_subtitle_path));
  365.                 }
  366.                 Log.d(LOG_TAG, "changeSubtitlePath result : " + result);
  367.             }
  368.         });
  369.  
  370.  
  371.         mPlayListUtil = new PlayListUtils(getResources().getStringArray(R.array.playable_extension_list));
  372.        
  373.         getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
  374.         getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
  375.         setContentView(R.layout.nexplayer_sample);
  376.  
  377.         mAdUiContainer = (ViewGroup) findViewById(R.id.videoPlayerWithAdPlayback);
  378.  
  379.         getIntentExtra();
  380.         setBroadcastReceiver();
  381.         setUIComponents();
  382.  
  383.         if( setPlayer() < 0 ) {
  384.             mPlayerState = PLAYER_FLOW_STATE.END_OF_ONERROR;
  385.             return;
  386.         }
  387.  
  388.         mNexPlayer.getContentInfo().mIsSeekable = 1;
  389.  
  390.         // Youbora
  391.         YBLog.setDebugLevel(YBLog.YBLogLevelHTTPRequests);
  392.  
  393.         youboraPlugin = new PluginNexStreaming(YouboraConfigManager.getYouboraConfig(this));
  394.  
  395.         youboraPlugin.startMonitoring(mNexPlayer);
  396.  
  397.         if( mPrefData.mShowCaptionDownloadDialog ) {
  398.             mCaptionDownloadDialog = new CaptionDownloadDialog(this, new CaptionDownloadDialog.CaptionDownloadIListener() {
  399.                 @Override
  400.                 public void onCaptionDownloadComplete(int result, String captionPath) {
  401.                     Log.d("captiondown", "onCaptionDownloadComplete result : " + result + " captionPath : " + captionPath);
  402.                     mTargetSubtitlePath = captionPath;
  403.                     startPlay();
  404.                 }
  405.             });
  406.             mCaptionDownloadDialog.createAndShowDialog();
  407.         } else {
  408.             startPlay();
  409.         }
  410.  
  411.         mToolbar.requestFocus();
  412.  
  413.         //Google IMA
  414.         mSdkFactory = ImaSdkFactory.getInstance();
  415.         mAdsLoader = mSdkFactory.createAdsLoader(this);
  416.  
  417.         mAdsLoader.addAdErrorListener(new AdErrorEvent.AdErrorListener() {
  418.             @Override
  419.             public void onAdError(AdErrorEvent adErrorEvent) {
  420.  
  421.             }
  422.         });
  423.         mAdsLoader.addAdsLoadedListener(new AdsLoader.AdsLoadedListener() {
  424.             @Override
  425.             public void onAdsManagerLoaded(AdsManagerLoadedEvent adsManagerLoadedEvent) {
  426.                 // Ads were successfully loaded, so get the AdsManager instance. AdsManager has
  427.                 // events for ad playback and errors.
  428.                 mAdsManager = adsManagerLoadedEvent.getAdsManager();
  429.  
  430.                 // Attach event and error event listeners.
  431.                 mAdsManager.addAdErrorListener(new AdErrorEvent.AdErrorListener() {
  432.                     @Override
  433.                     public void onAdError(AdErrorEvent adErrorEvent) {
  434.  
  435.                     }
  436.                 });
  437.                 mAdsManager.addAdEventListener(new AdEvent.AdEventListener() {
  438.                     @Override
  439.                     public void onAdEvent(AdEvent adEvent) {
  440.                         switch (adEvent.getType()) {
  441.                             case LOADED:
  442.                                 // AdEventType.LOADED will be fired when ads are ready to be played.
  443.                                 // AdsManager.start() begins ad playback. This method is ignored for VMAP or
  444.                                 // ad rules playlists, as the SDK will automatically start executing the
  445.                                 // playlist.
  446.                                 mAdsManager.start();
  447.                                 break;
  448.                             case CONTENT_PAUSE_REQUESTED:
  449.                                 // AdEventType.CONTENT_PAUSE_REQUESTED is fired immediately before a video
  450.                                 // ad is played.
  451.                                 mIsAdDisplayed = true;
  452.                                 youboraPlugin.pauseMonitoring();
  453.                                 mNexPlayer.pause();
  454.                                 break;
  455.                             case CONTENT_RESUME_REQUESTED:
  456.                                 // AdEventType.CONTENT_RESUME_REQUESTED is fired when the ad is completed
  457.                                 // and you should start playing your content.
  458.                                 mIsAdDisplayed = false;
  459.                                 mNexPlayer.resume();
  460.                                 youboraPlugin.resumeMonitoring();
  461.                                 break;
  462.                             case ALL_ADS_COMPLETED:
  463.                                 if (mAdsManager != null) {
  464.                                     mAdsManager.destroy();
  465.                                     mAdsManager = null;
  466.                                 }
  467.                                 break;
  468.                             case STARTED:
  469.  
  470.                                 break;
  471.                             default:
  472.                                 break;
  473.                         }
  474.                     }
  475.                 });
  476.                 mAdsManager.init();
  477.             }
  478.         });
  479.     }
  480.  
  481.     @Override
  482.     public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
  483.         Log.d(LOG_TAG, "onPictureInPictureModeChanged   isInPictureInPictureMode : " + isInPictureInPictureMode);
  484.         if (isInPictureInPictureMode) {
  485.             mHaveToResizeVideoViewInPIPMode = true;
  486.             setControllerVisibility(View.INVISIBLE);
  487.             // Hide the controls in picture-in-picture mode.
  488.         } else {
  489.             setControllerVisibility(View.VISIBLE);
  490.             // Restore the playback UI based on the playback status.
  491.         }
  492.         super.onPictureInPictureModeChanged(isInPictureInPictureMode);
  493.     }
  494.  
  495.  
  496.     private IDolbyListener mDolbyDialogListener = new IDolbyListener() {
  497.  
  498.         @Override
  499.         public void onDolbyDialogUpdated(DolbyDialog.DOLBY_BUTTON button, int value) {
  500.             Log.d(LOG_TAG, "onDolbyDialogUpdated button : " + button + " value : " + value);
  501.             switch (button) {
  502.                 case DOLBY_END_POINT:
  503.                     changeDolbyEndPointValue(value);
  504.                     break;
  505.                 case DOLBY_ENHANCEMENT_GAIN:
  506.                     changeDolbyEnhancementGainValue(value);
  507.                     break;
  508.                 case DOLBY_POST_PROCESSING:
  509.                     changeDolbyPostProcessingValue(value);
  510.                     break;
  511.             }
  512.         }
  513.     };
  514.  
  515.     private void setPreloader() {
  516.         if( !PlayerEnginePreLoader.isLoaded() ) {
  517.             Log.d(LOG_TAG, "Load NexPlayerEngine Library");
  518.             int codecMode = mPrefData.mPreloadHWOnly ? 2 : mPrefData.mCodecMode;
  519.             String libraryPath = this.getApplicationInfo().dataDir+"/" ;
  520.             PlayerEnginePreLoader.Load(libraryPath, this, codecMode);
  521.         }
  522.     }
  523.  
  524.     @Override
  525.     protected void onPause() {
  526.         mForeground = false;
  527.  
  528.         if (mNexPlayer != null && mNexPlayer.isInitialized()) {
  529.             if (mFastPlay)
  530.                 stopFastPlay();
  531.  
  532.             if ( mPrefData.mHomeButtonMode == NexPreferenceData.HOME_BUTTON_MODE_STOP ) {
  533.                 if ( mNexPlayer.getState() >= NexPlayer.NEXPLAYER_STATE_STOP ) {
  534.                     mNeedStartSeekBarTime = true;
  535.                     mNexPlayer.stop();
  536.                 }
  537.             } else {
  538.                 mNexPlayer.pause();
  539.             }
  540.             mPlayPauseButton.setImageResource(android.R.drawable.ic_media_play);
  541.         }
  542.  
  543.         mToolbar.getMenu().close();
  544.  
  545.         if(mVideoView != null)
  546.             mVideoView.onPause();
  547.  
  548.         youboraPlugin.pauseMonitoring();
  549.  
  550.         super.onPause();
  551.     }
  552.  
  553.     @Override
  554.     protected void onResume() {
  555.  
  556.         youboraPlugin.resumeMonitoring();
  557.  
  558.         mForeground = true;
  559.         if(mVideoView != null)
  560.             mVideoView.onResume();
  561.  
  562.         //stopped by onPause
  563.         resetPlayerStatus(RESET_PLAYER_BASIC);
  564.  
  565.         KeyguardManager keyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
  566.         if (keyguardManager != null) {
  567.             if (!keyguardManager.inKeyguardRestrictedInputMode()) {
  568.                 if ( mPrefData.mHomeButtonMode == NexPreferenceData.HOME_BUTTON_MODE_STOP )
  569.                     startPlayer();
  570.                 else {
  571.                     mNeedResume = mFastPlay ? false : true;
  572.                     resumePlayer();
  573.                 }
  574.             }
  575.         }
  576.  
  577.         super.onResume();
  578.     }
  579.  
  580.     @Override
  581.     protected void onStart() {
  582.         super.onStart();
  583.         mForeground = true;
  584.         resetPlayerStatus(RESET_PLAYER_BASIC);
  585.  
  586.         KeyguardManager keyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
  587.         if (keyguardManager != null) {
  588.             if (!keyguardManager.inKeyguardRestrictedInputMode()) {
  589.                 if ( mPrefData.mHomeButtonMode == NexPreferenceData.HOME_BUTTON_MODE_STOP )
  590.                     startPlayer();
  591.                 else {
  592.                     mNeedResume = !mFastPlay;
  593.                     resumePlayer();
  594.                 }
  595.             }
  596.         }
  597.     }
  598.  
  599.     @Override
  600.     protected void onStop() {
  601.         super.onStop();
  602.         Log.d(LOG_TAG, "onStop");
  603.         mForeground = false;
  604.  
  605.         if (mNexPlayer != null && mNexPlayer.isInitialized()) {
  606.             if (mFastPlay)
  607.                 stopFastPlay();
  608.  
  609.             if ( mPrefData.mHomeButtonMode == NexPreferenceData.HOME_BUTTON_MODE_STOP ) {
  610.                 if ( mNexPlayer.getState() >= NexPlayer.NEXPLAYER_STATE_STOP ) {
  611.                     mNeedStartSeekBarTime = true;
  612.                     mNexPlayer.stop();
  613.                 }
  614.             } else {
  615.                 mNexPlayer.pause();
  616.             }
  617.             mPlayPauseButton.setImageResource(android.R.drawable.ic_media_play);
  618.         }
  619.  
  620.         mToolbar.getMenu().close();
  621.     }
  622.  
  623.     private void resumePlayer() {
  624.         if( mNexPlayer.getState()==NexPlayer.NEXPLAYER_STATE_PAUSE && !mIsHeadsetRemoved || mNeedResume ) {
  625.             mNexPlayer.resume();
  626.             mNeedResume = false;
  627.         }
  628.     }
  629.  
  630.     private void startPlayer() {
  631.         if( mNexPlayer.getState() == NexPlayer.NEXPLAYER_STATE_STOP &&
  632.                 mPlayerState != PLAYER_FLOW_STATE.BEGINNING_OF_ONERROR &&
  633.                         mPlayerState != PLAYER_FLOW_STATE.END_OF_ONERROR ) {
  634.             int startSec = (mIsLive ? 0: mSeekBar.getProgress());
  635.  
  636.             if( !mNeedStartSeekBarTime ) {
  637.                 startSec = mPrefData.mStartSec * 1000;
  638.             }
  639.             mNeedStartSeekBarTime = false;
  640.             mNexPlayer.start(startSec);
  641.             mSeekBar.setCurrentTimeText(startSec);
  642.         }
  643.     }
  644.    
  645.     private void resetPlayerStatus(int resetMode) {
  646.         switch (resetMode) {
  647.             case RESET_PLAYER_ALL:
  648.                 mStrExternalPDFile = null;
  649.                 mExternalPDBufferDuration = 0;
  650.                 mVideoWidth = 0;
  651.                 mVideoHeight = 0;
  652.                 mIsLive = false;
  653.                 mAudioInitEnd = false;
  654.                 mContentInfo = null;
  655.                 mTempVideoStreamID = NexPlayer.MEDIA_STREAM_DEFAULT_ID;
  656.                 mCEA608CaptionChannel = 1;
  657.             case RESET_PLAYER_PROGRESS:
  658.             case RESET_PLAYER_BASIC:
  659.                 resetSeekStatus();
  660.                 mCaptionLanquageDialog.reset();
  661.                 break;
  662.             default:
  663.                 break;
  664.         }
  665.  
  666.         mHandler.post(new Runnable() {
  667.             int mode;
  668.  
  669.             public Runnable init(int resetMode) {
  670.                 this.mode = resetMode;
  671.                 return(this);
  672.             }
  673.  
  674.             @Override
  675.             public void run() {
  676.  
  677.                 mTimedMetaTextView.setText("");
  678.                 mCaptionPainter.clear();
  679.  
  680.                 switch (mode) {
  681.                     case RESET_PLAYER_ALL:
  682.                         mSeekBar.resetSeekBarStatus();
  683.  
  684.                         mErrorView.setVisibility(View.INVISIBLE);
  685.                         mErrorView.requestLayout();
  686.                         mGoToLiveButton.setVisibility(View.INVISIBLE);
  687.                         mGoToLiveButton.requestLayout();
  688.  
  689.                         mImageView.setImageResource(R.drawable.audio_skin2);
  690.                         mImageView.setVisibility(View.INVISIBLE);
  691.                         mLyricTextView.setText("");
  692.                         mLyricView.setText("");
  693.  
  694.                         mTrackView.setText("Track : " + 0);
  695.  
  696.                         mCaptionPainter.setCaptionType(mPrefData.mCaptionMode == 0 ? NexContentInformation.NEX_TEXT_CEA608 : NexContentInformation.NEX_TEXT_CEA708);
  697.  
  698.                     case RESET_PLAYER_PROGRESS:
  699.                         mSeekBar.setProgress(0);
  700.                     case RESET_PLAYER_BASIC:
  701.                         mPlayPauseButton.setImageResource(android.R.drawable.ic_media_play);
  702.                         if( mTargetBandWidthDialog.isShowing() )
  703.                             mTargetBandWidthDialog.dismiss();
  704.                         break;
  705.                     default:
  706.                         break;
  707.                 }
  708.             }
  709.         }.init(resetMode));
  710.     }
  711.    
  712.     @Override
  713.     protected void onDestroy() {
  714.         youboraPlugin.stopMonitoring();
  715.  
  716.         setupTimer(false);
  717.         stopDownload();
  718.         stopPlayer();
  719.         releasePlayer();
  720.         mVideoView.release();
  721.         unregisterReceivers();
  722.         PlayerEnginePreLoader.deleteAPKAsset(this);
  723.         if(mCurrentPath != null) {
  724.             getContentPath(REPLAY_MODE_QUIT);
  725.         }
  726.         super.onDestroy();
  727.     }
  728.    
  729.     private void enableDynamicThumbnail() {
  730.         if( mPrefData.mEnableDynamicThumbnail )
  731.             mNexPlayer.enableDynamicThumbnail();
  732.     }
  733.    
  734.     private void disableDynamicThumbnail() {
  735.         if( mPrefData.mEnableDynamicThumbnail ) {
  736.             mNexPlayer.disableDynamicThumbnail();
  737.             mSeekBar.enableDynamicThumbnail(false);
  738.             mSeekBar.resetThumbnailStatus();
  739.         }
  740.     }
  741.    
  742.     private void closePlayer() {
  743.         disableDynamicThumbnail();
  744.         mNexPlayer.close();
  745.     }
  746.    
  747.     private void stopPlayer() {
  748.         mHandler.removeCallbacks(updateStatisticsThread);
  749.        
  750.         if( mNexPlayer.getState() > NexPlayer.NEXPLAYER_STATE_STOP ) {
  751.             mNexPlayer.stop();
  752.             try {
  753.                 while(mNexPlayer.getState() !=NexPlayer.NEXPLAYER_STATE_STOP) {
  754.                     Thread.sleep(100);
  755.                 }
  756.             }
  757.             catch (InterruptedException e) {
  758.                 Log.e(LOG_TAG, "Exception - stopPlayer() : " + e.getMessage());
  759.             }
  760.         }
  761.     }
  762.    
  763.     private void unregisterReceivers() {
  764.         unregisterReceiver(mBroadcastReceiver);
  765.         NetworkBroadcastReceiver.removeListener(this);
  766.     }
  767.  
  768.     private void stopDownload() {
  769.         try {
  770.             if(mStrExternalPDFile != null) {
  771.                 int dw_tries = 0;
  772.                 if(NexPlayer.NEXDOWNLOADER_STATE_DOWNLOAD == mDownloaderState) {
  773.                     mNexPlayer.DownloaderStop();
  774.                 }
  775.                 else if (mDownloaderState == NexPlayer.NEXDOWNLOADER_STATE_STOP) {
  776.                     mNexPlayer.DownloaderClose();
  777.                 }
  778.                 while (NexPlayer.NEXDOWNLOADER_STATE_CLOSED != mDownloaderState) {
  779.                     if (NexPlayer.NEXDOWNLOADER_STATE_NONE == mDownloaderState) {
  780.                         break;
  781.                     }
  782.                     if (dw_tries > 30) {
  783.                         break;
  784.                     }
  785.                     Thread.sleep(100);
  786.                     dw_tries++;
  787.                 }          
  788.             }
  789.         }
  790.         catch (Exception e) {
  791.             Log.e(LOG_TAG, "Exception - stopDownload() : " + e.getMessage());
  792.         }
  793.     }
  794.  
  795.     private void releasePlayer() {
  796.         try {
  797.             if (mNexPlayer != null) {
  798.                 if (mNexPlayer.getState() > NexPlayer.NEXPLAYER_STATE_CLOSED) {
  799.                     closePlayer();         
  800.                 }
  801.                 mNexPlayer.release();
  802.                 mNexALFactory.release();
  803.             }
  804.         }
  805.         catch (Exception e) {
  806.             Log.e(LOG_TAG, "Exception - releasePlayer() : " + e.getMessage());
  807.         }
  808.     }
  809.    
  810.     @SuppressWarnings("unchecked")
  811.     private void getIntentExtra() {
  812.         Intent intent = getIntent();
  813.        
  814.         Uri uri = intent.getData();
  815.        
  816.         if(uri != null) {
  817.             mIsStreaming = false;
  818.             String tmpString;
  819.  
  820.             String proj[] = { MediaStore.Video.Media._ID,
  821.                     MediaStore.Video.Media.DATA};
  822.  
  823.             ContentResolver cr = getContentResolver();
  824.             Cursor videoCursor = null;
  825.             try {
  826.                 videoCursor = cr.query(uri, proj, null, null, null);
  827.             }
  828.             catch(Exception e) {
  829.                 Log.e(LOG_TAG, "Exception - getIntentExtra() : " + e.getMessage());
  830.             }
  831.            
  832.             if (videoCursor != null && videoCursor.moveToFirst()) {
  833.                 int videoDataCol = videoCursor
  834.                         .getColumnIndex(MediaStore.Video.Media.DATA);
  835.                 String url = videoCursor.getString(videoDataCol);
  836.                
  837.                 if (url != null && url.length() > 0) {
  838.                     mCurrentPath = url;
  839.                 }
  840.                
  841.                 videoCursor.close();
  842.             }
  843.             else {
  844.                 tmpString = Uri.decode(uri.toString());
  845.  
  846.                 if (tmpString.startsWith("http://")
  847.                         || tmpString.startsWith("https://")
  848.                         || tmpString.startsWith("rtsp://")
  849.                         || tmpString.startsWith("mms://")) {
  850.                     mIsStreaming = true;
  851.                     mCurrentPath = tmpString;
  852.                 } else if (tmpString.startsWith("file://")) {
  853.                     String path = tmpString.replaceFirst("file://", "");
  854.                     mCurrentPath = path;
  855.                     mTargetSubtitlePath = NexFileIO.subtitlePathFromMediaPath(mCurrentPath);
  856.                 }
  857.             }
  858.            
  859.         }
  860.         else {
  861.             mFileList = (ArrayList<File>) intent.getSerializableExtra("data");
  862.             mNxbWholeList = (ArrayList<NxbInfo>) intent.getSerializableExtra("wholelist");
  863.  
  864.             mCurrentPosition = intent.getIntExtra("selectedItem", 0);
  865.  
  866.             if (mFileList != null)
  867.             {
  868.                 mIsStreaming = false;
  869.                 mCurrentPath = mFileList.get(mCurrentPosition).getAbsolutePath();
  870.                 mTargetSubtitlePath = NexFileIO.subtitlePathFromMediaPath(mCurrentPath);
  871.             }
  872.             else
  873.             {
  874.                 mIsStreaming = true;
  875.                 mCurrentPath = intent.getStringExtra("theSimpleUrl");
  876.                 if ( mCurrentPath != null ) {
  877.                     mCurrentPath = mCurrentPath.trim();
  878.                 }
  879.  
  880.                 mCurrentExtraData =  getNxbExtraData();
  881.                 mTargetSubtitlePath = getFirstSubtitlePath();
  882.             }
  883.         }
  884.     }
  885.  
  886.     private String getNxbExtraData() {
  887.         String extraData = null;
  888.         NxbInfo info = NxbInfo.getNxbInfo(mNxbWholeList, mCurrentPath, mCurrentPosition);
  889.         extraData = info.getExtra();
  890.         return extraData;
  891.     }
  892.  
  893.     private boolean isNeededExtraSetting() {
  894.         NxbInfo info = NxbInfo.getNxbInfo(mNxbWholeList, mCurrentPath, mCurrentPosition);
  895.         Log.d(LOG_TAG, "isNeededExtraSetting info.getType() : " + info.getType());
  896.         boolean ret = info.getType().equalsIgnoreCase(NxbInfo.TYPE_MEDIA_DRM);
  897.         if( !ret ) {
  898.             if( mCurrentPath.endsWith(NexFileIO.STORE_INFO_EXTENSION) ) {
  899.                 JSONObject obj = NexStoredInfoFileUtils.parseJSONObject(new File(mCurrentPath));
  900.                 if( obj != null ) {
  901.                     try {
  902.                         ret = !TextUtils.isEmpty(obj.getString(NexStoredInfoFileUtils.STORED_INFO_KEY_MEDIA_DRM_KEY_SERVER_URI));
  903.                     } catch (JSONException e) {
  904.                         e.printStackTrace();
  905.                     }
  906.                 }
  907.             }
  908.         }
  909.  
  910.         return ret;
  911.     }
  912.  
  913.     // NexWVDRM start
  914.     private boolean isNeededExtraSettingForWVDRM() {
  915.         NxbInfo info = NxbInfo.getNxbInfo(mNxbWholeList, mCurrentPath, mCurrentPosition);
  916.         Log.d(LOG_TAG, "isNeededExtraSetting info.getType() : " + info.getType());
  917.         boolean ret = info.getType().equalsIgnoreCase(NxbInfo.TYPE_WV_DRM);
  918.         //do sth
  919.         return ret;
  920.     }
  921.     // NexWVDRM end
  922.  
  923.     private String getFirstSubtitlePath() {
  924.         String path = null;
  925.         NxbInfo info = NxbInfo.getNxbInfo(mNxbWholeList, mCurrentPath, mCurrentPosition);
  926.         if( info.getSubtitle().size() > 0 )
  927.             path = info.getSubtitle().get(0);
  928.         return path;
  929.     }
  930.    
  931.     private void setBroadcastReceiver() {
  932.         IntentFilter filter = new IntentFilter();
  933.         filter.addAction(Intent.ACTION_HEADSET_PLUG);
  934.         filter.addAction(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
  935.         NetworkBroadcastReceiver.addListener(this);
  936.  
  937.         mBroadcastReceiver = new BroadcastReceiver() {
  938.             public void onReceive(Context context, Intent intent) {
  939.                 if (intent.getAction().equals(AudioManager.ACTION_AUDIO_BECOMING_NOISY)) {
  940.                     if (mNexPlayer.getState() == NexPlayer.NEXPLAYER_STATE_PLAY) {
  941.                         mNexPlayer.pause();
  942.                         mPlayPauseButton.setImageResource(android.R.drawable.ic_media_play);
  943.                        
  944.                     }
  945.                     else if(mIsBuffering || mIsSeeking) {
  946.                         mIsHeadsetRemoved = true;
  947.                     }
  948.                 }
  949.                 else if( intent.getAction().equals(Intent.ACTION_HEADSET_PLUG) ) {
  950.                     int headSetState = intent.getExtras().getInt("state");
  951.                     if( mNexPlayer != null ) {
  952.                         mNexPlayer.notifyHeadsetState(headSetState);
  953.                     }
  954.                 }
  955.             }
  956.         };
  957.         registerReceiver(mBroadcastReceiver, filter);
  958.     }
  959.    
  960.     private void setUIComponents() {
  961.         mTrackView = (TextView)findViewById(R.id.cur_video_track_text_view);
  962.         setVisibilityLayout();
  963.         setVideoRendererView();
  964.         setCaptionPainter();
  965.         setAlbumImageView();
  966.         setLyricView();
  967.         setThumbnailView();
  968.         setGoToLiveButton();
  969.         setSeekLayout();
  970.         setErrorView();
  971.         setControlButton();
  972.         setBufferComponent();
  973.         setTimeMeta();
  974.         setupTimedMetaCheckBox();
  975.         setupToolbar();
  976.     }
  977.  
  978.     private void setupTimedMetaCheckBox() {
  979.         final CheckBox check = (CheckBox)findViewById(R.id.check_timed_meta_text);
  980.         check.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
  981.             @Override
  982.             public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
  983.                 int visibility = View.VISIBLE;
  984.                 int stringRes = R.string.show_timed_meta_text;
  985.  
  986.                 if( !isChecked ) {
  987.                     visibility = View.INVISIBLE;
  988.                     stringRes = R.string.hide_timed_meta_text;
  989.                 }
  990.  
  991.                 mTimedMetaTextView.setVisibility(visibility);
  992.                 check.setText(stringRes);
  993.             }
  994.         });
  995.     }
  996.  
  997.     private void setupToolbar() {
  998.         mToolbar = (Toolbar)findViewById(R.id.tool_bar);
  999.         mToolbar.setTitle("");
  1000.         setSupportActionBar(mToolbar);
  1001.         getSupportActionBar().setDisplayHomeAsUpEnabled(true);
  1002.     }
  1003.  
  1004.     private void setTimeMeta() {
  1005.         mTimedMetaTextView = (TextView)findViewById(R.id.time_meta_textview);
  1006.         mLyricTextView = (TextView)findViewById(R.id.time_lyirc_textview);
  1007.         mLyricTextView.setGravity(Gravity.CENTER);
  1008.         mLyricTextView.setTextColor(Color.RED);
  1009.         mTimedMetaTextView.setText("");
  1010.     }
  1011.  
  1012.     private void setGoToLiveButton() {
  1013.         mGoToLiveButton = (NexImageButton)findViewById(R.id.go_to_live_button);
  1014.         mGoToLiveButton.setOnClickListener(new OnClickListener() {
  1015.            
  1016.             @Override
  1017.             public void onClick(View v) {
  1018.                 long[] seekableRange = mNexPlayer.getSeekableRangeInfo();
  1019.            
  1020.                 if(seekableRange != null) {
  1021.                     int seekbarCriterion = (int)seekableRange[0];
  1022.                     int seekbarMaxLength = (int)seekableRange[1] - seekbarCriterion;
  1023.                     mProgressBase = 0;
  1024.                    
  1025.                     mSeekBar.setMax(seekbarMaxLength);
  1026.                     mSeekBar.setProgress(seekbarMaxLength);
  1027.                     mNexPlayer.gotoCurrentLivePosition();
  1028.                 }
  1029.             }
  1030.         });
  1031.     }
  1032.     private void setBufferComponent() {
  1033.         mProgressLayout = (RelativeLayout)findViewById(R.id.progress_layout);
  1034.         mProgressTextView = (TextView)findViewById(R.id.progress_text);
  1035.     }
  1036.  
  1037.     @SuppressLint("NewApi")
  1038.     private void setVideoRendererView() {
  1039.         {
  1040.             mVideoView = (NexVideoRenderer)findViewById(R.id.videoview);
  1041.             boolean useSurfaceTexture = mPrefData.mUseSurfaceTextrue;
  1042.             boolean useRenderThreadWithSurfaceTexture = mPrefData.mUseRenderThread;
  1043.             ((NexVideoRenderer)mVideoView).setUseSurfaceTexture(useSurfaceTexture, useRenderThreadWithSurfaceTexture);
  1044.         }
  1045.  
  1046.         mVideoView.setVisibility(View.VISIBLE);
  1047.         if(mPrefData.mColorSpace == 1)
  1048.             mVideoView.setScreenPixelFormat(PixelFormat.RGB_565);
  1049.         else
  1050.             mVideoView.setScreenPixelFormat(PixelFormat.RGBA_8888);
  1051.  
  1052.         mVideoView.setListener(new NexVideoRenderer.IListener()
  1053.         {
  1054.  
  1055.             @Override
  1056.             public void onVideoSizeChanged()
  1057.             {
  1058.                 Point videoSize = new Point();
  1059.                 mVideoView.getVideoSize(videoSize);
  1060.                 mVideoWidth = videoSize.x;
  1061.                 mVideoHeight = videoSize.y;
  1062.  
  1063.                 setPlayerOutputPosition(mScaleMode);
  1064.             }
  1065.  
  1066.             @Override
  1067.             public void onSizeChanged()
  1068.             {
  1069.                 if( !supportPIP() ||
  1070.                         (supportPIP() && !isInPictureInPictureMode()) ||
  1071.                         (supportPIP() && isInPictureInPictureMode() && mHaveToResizeVideoViewInPIPMode) ) {
  1072.                     if(mHaveToResizeVideoViewInPIPMode)
  1073.                         mHaveToResizeVideoViewInPIPMode = false;
  1074.  
  1075.                     setPlayerOutputPosition(mScaleMode);
  1076.                 }
  1077.             }
  1078.  
  1079.             @Override
  1080.             public void onFirstVideoRenderCreate()
  1081.             {
  1082.                 /* Initialization of mScaleMode has been done at the Activity Instance Initialization
  1083.                  * Not every time a new playback begins: NPDS-2404
  1084.                  */
  1085.                 setPlayerOutputPosition(mScaleMode);
  1086.             }
  1087.  
  1088.             @Override
  1089.             public void onDisplayedRectChanged()
  1090.             {
  1091.             }
  1092.         });
  1093.         mVideoView.setPostNexPlayerVideoRendererListener(mEventReceiver);
  1094.     }
  1095.  
  1096.     private void setCaptionPainter() {
  1097.         mCaptionPainter = (NexCaptionPainter) findViewById(R.id.NexCaptionPainter);
  1098.     }
  1099.    
  1100.     private void setAlbumImageView() {
  1101.         mImageView = (ImageView)findViewById(R.id.imageview);
  1102.         mImageView.setImageResource(R.drawable.audio_skin2);
  1103.         mImageView.setBackgroundColor(Color.BLACK);
  1104.         mImageView.setVisibility(View.INVISIBLE);
  1105.     }
  1106.    
  1107.     private void setLyricView() {
  1108.         mLyricScrollView = (ScrollView)findViewById(R.id.lyric_scrollview);
  1109.         mLyricView = (TextView)findViewById(R.id.lyricview);
  1110.         mLyricView.setOnClickListener(mOnClickListener);
  1111.     }
  1112.    
  1113.     private void setThumbnailView() {
  1114.         mThumbnailView = (ImageView)findViewById(R.id.thumbnailView);
  1115.         mThumbnailView.setVisibility(View.INVISIBLE);
  1116.     }
  1117.    
  1118.     OnClickListener mOnClickListener = new View.OnClickListener() {
  1119.        
  1120.         @Override
  1121.         public void onClick(View v) {
  1122.             setControllerVisibility(mVisibilityLayout.getVisibility() == View.VISIBLE ? View.INVISIBLE : View.VISIBLE);
  1123.         }
  1124.     };
  1125.    
  1126.     private void setVisibilityLayout() {
  1127.         mVisibilityLayout = (ViewGroup)findViewById(R.id.visibility_layout);
  1128.         mParentView = (RelativeLayout)findViewById(R.id.parent_view);
  1129.         mParentView.setOnClickListener(mOnClickListener);
  1130.         mParentView.setBackgroundColor(Color.BLACK);
  1131.     }
  1132.    
  1133.     private void setControllerVisibility(final int visibility) {
  1134.         mHandler.post(new Runnable() {
  1135.  
  1136.             @Override
  1137.             public void run() {
  1138.                 mVisibilityLayout.setVisibility(visibility);
  1139.                 mVisibilityLayout.requestLayout();
  1140.                 CheckBox check = (CheckBox)findViewById(R.id.check_timed_meta_text);
  1141.                 check.setVisibility(visibility);
  1142.                 ActionBar toolbar = getSupportActionBar();
  1143.                 if( toolbar != null ) {
  1144.                     if (visibility == View.VISIBLE && !toolbar.isShowing()) {
  1145.                         toolbar.show();
  1146.                     } else if (visibility == View.INVISIBLE && toolbar.isShowing()) {
  1147.                         toolbar.hide();
  1148.                     }
  1149.                 }
  1150.             }
  1151.         });
  1152.     }
  1153.  
  1154.     private void createAndShowContentInfoDialog() {
  1155.         if( mContentInfo != null ) {
  1156.             if( mContentInfoDialog == null )
  1157.                 mContentInfoDialog = new NexContentInfoDialog(this, new NexContentInfoDialog.IListener() {
  1158.                     @Override
  1159.                     public int getAC3DecoderType() {
  1160.                         return mNexPlayer.getProperties(DolbyDialog.AC3_PROPERTY_DECODER_TYPE);
  1161.                     }
  1162.                 });
  1163.  
  1164.             mContentInfoDialog.setContentInfo(mContentInfo);
  1165.             mContentInfoDialog.show();
  1166.         }
  1167.     }
  1168.  
  1169.     private void setSeekLayout() {
  1170.         mSeekBar = (ThumbnailSeekBar)findViewById(R.id.seek_layout);
  1171.         mSeekBar.setOnSeekBarChangeListener(new ThumbnailSeekBar.ISeekBarListener() {
  1172.  
  1173.             @Override
  1174.             public void onStopTrackingTouch(SeekBar seekBar) {
  1175.                 if (mNexPlayer != null && mForeground) {
  1176.                     int state = mNexPlayer.getState();
  1177.  
  1178.                     if (mFastPlay)
  1179.                         stopFastPlay();
  1180.  
  1181.                     if (state > NexPlayer.NEXPLAYER_STATE_STOP) {
  1182.                         int position = seekBar.getProgress();
  1183.                         clearCaptionString();
  1184.  
  1185.                         boolean shouldSeek = true;
  1186.                         if (mIsLive) {
  1187.                             long[] seekableRange = mNexPlayer.getSeekableRangeInfo();
  1188.                             if (seekableRange != null) {
  1189.                                 position += (int) seekableRange[0];
  1190.                                 position = Math.min(position, (int) seekableRange[1]);
  1191.                             } else {
  1192.                                 shouldSeek = false;
  1193.                             }
  1194.                         } else if (mStrExternalPDFile != null) {
  1195.                             if (position > mExternalPDBufferDuration) {
  1196.                                 shouldSeek = false;
  1197.                             }
  1198.                         }
  1199.  
  1200.                         if (shouldSeek) {
  1201.                             if (mIsBuffering || mIsSeeking) {
  1202.                                 mSeekPoint = position;
  1203.                                 return;
  1204.                             }
  1205.  
  1206.                             mIsSeeking = (mNexPlayer.seek(position) == 0);
  1207.                         }
  1208.                     } else if (mNexPlayer != null && mPlayerState == PLAYER_FLOW_STATE.END_OF_ONERROR) {
  1209.                         mNeedStartSeekBarTime = true;
  1210.                     }
  1211.                 }
  1212.             }
  1213.  
  1214.             @Override
  1215.             public void onProgressChanged(SeekBar seekBar, int progress) {
  1216.                 if (mIsLive) {
  1217.                     progress += mProgressBase;
  1218.                 }
  1219.  
  1220.                 mSeekBar.setCurrentTimeText(progress);
  1221.             }
  1222.         });
  1223.     }
  1224.  
  1225.     private void setErrorView() {
  1226.         mErrorView = (TextView)findViewById(R.id.error_textview);
  1227.         mErrorView.setVisibility(View.INVISIBLE);
  1228.     }
  1229.        
  1230.     private void setControlButton() {
  1231.         setupPreviousButton();
  1232.         setupRewindButton();
  1233.         setupPlayPauseButton();
  1234.         setupFastForwardButton();
  1235.         setupNextButton();
  1236.     }
  1237.        
  1238.     private void setupPreviousButton() {
  1239.         mPreviousButton = (NexImageButton)findViewById(R.id.prev_button);
  1240.         mPreviousButton.setOnClickListener(new OnClickListener() {
  1241.  
  1242.             @Override
  1243.             public void onClick(View v) {
  1244.                 replay(REPLAY_MODE_PREVIOUS);
  1245.             }
  1246.         });
  1247.     }
  1248.        
  1249.     private void setupRewindButton() {
  1250.         mRewindButton = (NexImageButton)findViewById(R.id.rewind_button);
  1251.         mRewindButton.setOnClickListener(new OnClickListener() {
  1252.            
  1253.             @Override
  1254.             public void onClick(View v) {
  1255.                 if( mFastPlay ) {
  1256.                     changeFastPlaySpeed(FastPlayUtil.getFastPlaySpeed(mFastPlaySpeed, false));
  1257.                 } else {
  1258.                     rewind();
  1259.                 }
  1260.             }
  1261.         });
  1262.         mRewindButton.setOnLongClickListener(new View.OnLongClickListener() {
  1263.             @Override
  1264.             public boolean onLongClick(View v) {
  1265.                 int result = -1;
  1266.  
  1267.                 if (!mFastPlay) {
  1268.                     result = startFastPlay(FastPlayUtil.getFastPlaySpeed(mFastPlaySpeed, false));
  1269.                 }
  1270.  
  1271.                 return result == 0;
  1272.             }
  1273.         });
  1274.     }
  1275.  
  1276.     private void rewind() {
  1277.         if( mNexPlayer != null && mNexPlayer.isInitialized()
  1278.                 && (mNexPlayer.getState() > NexPlayer.NEXPLAYER_STATE_STOP) && mForeground) {
  1279.             int seekPosition = mSeekBar.getProgress() - (mPrefData.mSeekOffset * 1000);
  1280.             int min = 0;
  1281.             if( mSeekPoint >= 0 ) {
  1282.                 seekPosition = mSeekPoint - (mPrefData.mSeekOffset * 1000);
  1283.             }
  1284.  
  1285.             if( mIsLive ) {
  1286.                 long[] seekableRange = mNexPlayer.getSeekableRangeInfo();
  1287.                 if( seekableRange != null ) {
  1288.                     seekPosition += seekableRange[0];
  1289.                     min = (int)seekableRange[0];
  1290.                 }
  1291.             }
  1292.  
  1293.             seekPosition = Math.max(min, seekPosition);
  1294.  
  1295.             if( mIsBuffering || mIsSeeking ) {
  1296.                 mSeekPoint = seekPosition;
  1297.                 return;
  1298.             }
  1299.  
  1300.             mIsSeeking = (mNexPlayer.seek(seekPosition) == 0);
  1301.         }
  1302.     }
  1303.    
  1304.     private void setupNextButton() {
  1305.         mNextButton = (NexImageButton)findViewById(R.id.next_button);
  1306.         mNextButton.setOnClickListener(new OnClickListener() {
  1307.  
  1308.             @Override
  1309.             public void onClick(View v) {
  1310.                 replay(REPLAY_MODE_NEXT);
  1311.             }
  1312.         });
  1313.     }
  1314.  
  1315.     private void replay(int replayMode) {
  1316.         if (mPlayerState != PLAYER_FLOW_STATE.END_OF_COMPLETE &&
  1317.                 mPlayerState != PLAYER_FLOW_STATE.END_OF_ONERROR && mPlayerState != PLAYER_FLOW_STATE.START_PLAY) {
  1318.             return;
  1319.         }
  1320.  
  1321.         int state = mNexPlayer.getState();
  1322.  
  1323.         if( state != NexPlayer.NEXPLAYER_STATE_STOP &&
  1324.                 state != NexPlayer.NEXPLAYER_STATE_NONE ) {
  1325.             if (mFastPlay)
  1326.                 stopFastPlay();
  1327.  
  1328.             if (mStrExternalPDFile != null)
  1329.                 stopDownload();
  1330.  
  1331.             resetPlayerStatus(RESET_PLAYER_ALL);
  1332.             getContentPath(replayMode);
  1333.  
  1334.             if (state == NexPlayer.NEXPLAYER_STATE_CLOSED) {
  1335.                 startPlay();
  1336.             } else if (state > NexPlayer.NEXPLAYER_STATE_STOP) {
  1337.                 stopPlayer();
  1338.             }
  1339.         }
  1340.     }
  1341.    
  1342.     private void setupFastForwardButton() {
  1343.         mFastForwardButton = (NexImageButton)findViewById(R.id.fastforward_button);
  1344.         mFastForwardButton.setOnClickListener(new OnClickListener() {
  1345.            
  1346.             @Override
  1347.             public void onClick(View v) {
  1348.                 if( mFastPlay ) {
  1349.                     changeFastPlaySpeed(FastPlayUtil.getFastPlaySpeed(mFastPlaySpeed, true));
  1350.                 } else {
  1351.                     fastForward();
  1352.                 }
  1353.             }
  1354.         });
  1355.         mFastForwardButton.setOnLongClickListener(new View.OnLongClickListener() {
  1356.             @Override
  1357.             public boolean onLongClick(View v) {
  1358.                 int result = -1;
  1359.  
  1360.                 if (!mFastPlay) {
  1361.                     result = startFastPlay(FastPlayUtil.getFastPlaySpeed(mFastPlaySpeed, true));
  1362.                 }
  1363.  
  1364.                 return result == 0;
  1365.             }
  1366.         });
  1367.     }
  1368.  
  1369.     private void fastForward() {
  1370.         if(mNexPlayer != null && mNexPlayer.isInitialized()
  1371.                 && (mNexPlayer.getState() > NexPlayer.NEXPLAYER_STATE_STOP) && mForeground) {
  1372.             int position;
  1373.             int duration = mNexPlayer.getContentInfoInt(NexPlayer.CONTENT_INFO_INDEX_MEDIA_DURATION);
  1374.  
  1375.             if(mSeekPoint > -1) {
  1376.                 position = mSeekPoint + (mPrefData.mSeekOffset * 1000);
  1377.             }
  1378.             else {
  1379.                 position = mSeekBar.getProgress() + (mPrefData.mSeekOffset * 1000);
  1380.             }
  1381.  
  1382.             boolean shouldSeek = true;
  1383.             if ( mIsLive ) {
  1384.                 long[] seekableRange = mNexPlayer.getSeekableRangeInfo();
  1385.                 if ( seekableRange != null ) {
  1386.                     position += (int)seekableRange[0];
  1387.                     position = Math.min(position, (int)seekableRange[1]);
  1388.                 } else {
  1389.                     shouldSeek = false;
  1390.                 }
  1391.             } else if ( mStrExternalPDFile != null ) {
  1392.                 if ( position > mExternalPDBufferDuration ) {
  1393.                     shouldSeek = false;
  1394.                 }
  1395.             } else {
  1396.                 position = Math.min(position, duration);
  1397.             }
  1398.  
  1399.             if( shouldSeek ) {
  1400.                 if ( mIsBuffering || mIsSeeking ) {
  1401.                     mSeekPoint = position;
  1402.                     return;
  1403.                 }
  1404.  
  1405.                 mIsSeeking = (mNexPlayer.seek(position) == 0);
  1406.             }
  1407.         }
  1408.     }
  1409.    
  1410.     public void setupTimer(boolean enable)
  1411.     {
  1412.         if(clientTimeshiftTimer == null && enable)
  1413.         {
  1414.             int timerDuration = mPrefData.mTimeShiftMaxBufferDuration * 60 * 1000; //unit is min.
  1415.             clientTimeshiftTimer = new CountDownTimer(timerDuration, 60*1000) {
  1416.                
  1417.                 @Override
  1418.                 public void onTick(long millisUntilFinished) {
  1419.                    
  1420.                 }
  1421.                
  1422.                 @Override
  1423.                 public void onFinish() {
  1424.                     if(mNexPlayer.getState() == NexPlayer.NEXPLAYER_STATE_PAUSE)
  1425.                         mNexPlayer.resume();
  1426.                 }
  1427.             };
  1428.         }
  1429.        
  1430.         if(enable)
  1431.         {
  1432.             clientTimeshiftTimer.start();
  1433.         }
  1434.         else if(clientTimeshiftTimer != null && enable == false)
  1435.         {
  1436.             clientTimeshiftTimer.cancel();
  1437.             clientTimeshiftTimer = null;
  1438.         }
  1439.     }
  1440.    
  1441.     private void setupPlayPauseButton() {
  1442.         mPlayPauseButton = (NexImageButton)findViewById(R.id.play_pause_button);
  1443.         mPlayPauseButton.setOnClickListener(new OnClickListener() {
  1444.                
  1445.             @Override
  1446.             public void onClick(View v) {
  1447.                 if(mPlayerState != PLAYER_FLOW_STATE.END_OF_COMPLETE &&
  1448.                         mPlayerState != PLAYER_FLOW_STATE.END_OF_ONERROR) {
  1449.                     return;
  1450.                 }
  1451.                
  1452.                 if(mNexPlayer != null && mNexPlayer.isInitialized()) {
  1453.                     int state = mNexPlayer.getState();
  1454.                    
  1455.                     if( state == NexPlayer.NEXPLAYER_STATE_PLAY ) {
  1456.                         int ret = mNexPlayer.pause();
  1457.                         if(mIsLive &&  mPrefData.mEnableClientSideTimeShift && ret == 0)
  1458.                         {
  1459.                             //create timer.
  1460.                             NexPlayerSample.this.setupTimer(true);
  1461.                         }
  1462.                         mPlayPauseButton.setImageResource(android.R.drawable.ic_media_play);
  1463.                     }
  1464.                     else if( state == NexPlayer.NEXPLAYER_STATE_PAUSE ) {
  1465.                         int ret = mNexPlayer.resume();
  1466.                         if(mIsLive && mPrefData.mEnableClientSideTimeShift && ret == 0)
  1467.                         {
  1468.                             NexPlayerSample.this.setupTimer(false);
  1469.                         }
  1470.                         mPlayPauseButton.setImageResource(android.R.drawable.ic_media_pause);
  1471.                     }
  1472.                     else if( state == NexPlayer.NEXPLAYER_STATE_CLOSED ) {
  1473.                         mErrorView.setVisibility(View.INVISIBLE);
  1474.                         mErrorView.requestLayout();
  1475.                         startPlay();
  1476.                     }
  1477.                     else if( state == NexPlayer.NEXPLAYER_STATE_PLAYxN ) {
  1478.                         if( mFastPlay )
  1479.                             stopFastPlay();
  1480.                     }
  1481.                     else if( state == NexPlayer.NEXPLAYER_STATE_STOP ) {
  1482.                         startPlayer();
  1483.                     }
  1484.                 }
  1485.             }
  1486.         });
  1487.     }
  1488.  
  1489.     private void stopFastPlay() {
  1490.         mNexPlayer.fastPlayStop(mForeground ? true : false);
  1491.         mPlayPauseButton.setImageResource(android.R.drawable.ic_media_pause);
  1492.         mPlayPauseButton.setText("");
  1493.         mFastPlay = false;
  1494.         mFastPlaySpeed = 1.0f;
  1495.     }
  1496.  
  1497.     private int startFastPlay(float speed) {
  1498.         int result = -1;
  1499.         if( FastPlayUtil.isFastPlayPossible(mContentInfo, mPrefData.mMinBandWidth, mPrefData.mMaxBandWidth)
  1500.                 && mNexPlayer.getState() == NexPlayer.NEXPLAYER_STATE_PLAY ) {
  1501.             result = mNexPlayer.fastPlayStart(mNexPlayer.getCurrentPosition(), speed);
  1502.  
  1503.             if( result == 0 ) {
  1504.                 mFastPlaySpeed = speed;
  1505.                 mFastPlay = true;
  1506.                 mPlayPauseButton.setImageResource(android.R.drawable.ic_media_play);
  1507.                 mPlayPauseButton.setText("" + (int) mFastPlaySpeed + "X");
  1508.                 clearCaptionString();
  1509.             }
  1510.         }
  1511.         return result;
  1512.     }
  1513.  
  1514.     private void changeFastPlaySpeed(float speed) {
  1515.         int result = mNexPlayer.fastPlaySetPlaybackRate(speed);
  1516.         if( result == 0 ) {
  1517.             mFastPlaySpeed = speed;
  1518.             mPlayPauseButton.setText("" + (int) mFastPlaySpeed + "X");
  1519.         }
  1520.     }
  1521.  
  1522.     @SuppressLint("NewApi")
  1523.     private int setPlayer() {
  1524.         mNexPlayer = new NexPlayer();
  1525.         mNexALFactory = new NexALFactory();
  1526.         System.gc();
  1527.        
  1528.         int debugLogLevel = mPrefData.mLogLevel;
  1529.        
  1530.         if( debugLogLevel< 0 )
  1531.             debugLogLevel = 0xF0000000;
  1532.        
  1533.  
  1534.         //captionRenderer.createRenderView(this);
  1535.        
  1536.         if(mNexALFactory.init(this, android.os.Build.MODEL, mPrefData.mRenderMode,debugLogLevel, 1) == false) {
  1537.             showErrorStatus("ALFactory initialization failed");
  1538.             return -2;
  1539.         }
  1540.  
  1541.         mNexPlayer.setLicenseFile("/sdcard/test_lic.xml");
  1542.        
  1543.         mNexPlayer.setNexALFactory(mNexALFactory);
  1544.         if(mNexPlayer.init(this, mPrefData.mLogLevel) == false) {
  1545.             showErrorStatus("NexPlayer initialization failed");
  1546.             return -3;
  1547.         }
  1548.  
  1549.         setProperties();
  1550.  
  1551.         // If you want to set custom address by hostname, please use below codes.
  1552.         //setCustomNetAddrTable();
  1553.  
  1554.  
  1555.         addEventReceiver();
  1556.  
  1557.         mABRController = new NexABRController(mNexPlayer);
  1558.         mABRController.setIABREventListener(new NexABRController.IABREventListener() {
  1559.             @Override
  1560.             public void onMinMaxBandWidthChanged(NexErrorCode result, int minBwBps, int maxBwBps) {
  1561.                 if( result == NexErrorCode.NONE ) {
  1562.                     mPrefData.setMinMaxBandwidth(minBwBps/BANDWIDTH_KBPS, maxBwBps/BANDWIDTH_KBPS);
  1563.                 }
  1564.                 Log.d(LOG_TAG,"onMinMaxBandWidthChanged (Result : " + result +", Min : " + minBwBps + ",  Max : " + maxBwBps + ")");
  1565.             }
  1566.  
  1567.             @Override
  1568.             public void onTargetBandWidthChanged(NexErrorCode result, int reqBwBps, int selBwBps) {
  1569.                 //Log.d(LOG_TAG,"onTargetBandwidthChanged (Result : " + result +", Min : " + reqBwBps + ",  Max : " + selBwBps + ")");
  1570.             }
  1571.         });
  1572.  
  1573.         mVideoView.init(mNexPlayer);
  1574.         mVideoView.setVisibility(View.VISIBLE);
  1575.  
  1576.         return 0;
  1577.     }
  1578.  
  1579.     protected void addEventReceiver() {
  1580.         mEventReceiver = new NexEventReceiver() {
  1581.             @Override
  1582.             public void onAsyncCmdComplete(NexPlayer mp, int command, int result, int param1, int param2) {
  1583.                 super.onAsyncCmdComplete(mp, command, result, param1, param2);
  1584.  
  1585.                 Log.d(LOG_TAG, "onAsyncCmdComplete : mp : " + mp + " command : " + command + ", result : " + result);
  1586.                 switch (command) {
  1587.                     case NexPlayer.NEXPLAYER_ASYNC_CMD_OPEN_LOCAL:
  1588.                     case NexPlayer.NEXPLAYER_ASYNC_CMD_OPEN_STREAMING:
  1589.                         Log.d(LOG_TAG, "onAsyncCmdComplete : OPEN");
  1590.                         clearBufferStatus();
  1591.                         mPlayerState = PLAYER_FLOW_STATE.BEGINNING_OF_COMPLETE;
  1592.                         mIsEnginOpen = true;
  1593.  
  1594.                         if(result == 0) {
  1595.                             final int duration = mNexPlayer.getContentInfoInt(NexPlayer.CONTENT_INFO_INDEX_MEDIA_DURATION);
  1596.                             mContentInfo = mNexPlayer.getContentInfo();
  1597.                             if( mContentInfoDialog != null )
  1598.                                 mContentInfoDialog.setContentInfo(mContentInfo);
  1599.  
  1600.                             if ( !TextUtils.isEmpty(mTargetSubtitlePath) ){
  1601.                                 result = mNexPlayer.changeSubtitlePath(mTargetSubtitlePath);
  1602.                                 if( result != 0 && result != 1 ) {
  1603.                                     showToastMsg(getString(R.string.invalid_subtitle_path));
  1604.                                 }
  1605.                             }
  1606.  
  1607.                             if( duration < 0 ) {
  1608.                                 mIsLive = true;
  1609.                                 if( mIsStoreManagerInitialized ) {
  1610.                                     onError(mp, NexErrorCode.UNKNOWN);
  1611.                                     return;
  1612.                                 }
  1613.                             }
  1614.  
  1615.                             setDynamicThumbnailOption(mContentInfo);
  1616.                             updateControllerVisibility();
  1617.  
  1618.                             int textType = mContentInfo.mCaptionType;
  1619.  
  1620.                             if (textType == NexContentInformation.NEX_TEXT_CEA) {
  1621.                                 textType = mPrefData.mCaptionMode == 0 ? NexContentInformation.NEX_TEXT_CEA608 : NexContentInformation.NEX_TEXT_CEA708;
  1622.                             }
  1623.  
  1624.                             mCaptionPainter.setCaptionType(textType);
  1625.  
  1626.                             mHandler.post(new Runnable() {
  1627.                                 @Override
  1628.                                 public void run() {
  1629.                                     try {
  1630.                                         String text = "Track : " + NexContentInfoExtractor.getCurrTrackID(NexPlayer.MEDIA_STREAM_TYPE_VIDEO, mContentInfo);
  1631.                                         mTrackView.setText(text);
  1632.                                         setVolume();
  1633.                                         if( mCurrentPath != null )
  1634.                                             mToolbar.setTitle(NexFileIO.getContentTitle(mCurrentPath));
  1635.  
  1636.                                         mSeekBar.setMax(duration);
  1637.                                         mSeekBar.setDurationTimeText(duration);
  1638.  
  1639.                                         if(mContentInfo.mMediaType == 1) {
  1640.                                             setAlbumImage();
  1641.                                             setLyric();
  1642.                                         }
  1643.                                         else {
  1644.                                             mVideoWidth = mContentInfo.mVideoWidth;
  1645.                                             mVideoHeight = mContentInfo.mVideoHeight;
  1646.                                             setPlayerOutputPosition(mScaleMode);
  1647.                                             mImageView.setVisibility(View.INVISIBLE);
  1648.                                             mLyricView.setText("");
  1649.                                             mLyricScrollView.setVisibility(View.INVISIBLE);
  1650.                                         }
  1651.  
  1652.                                         if( mForeground ) {
  1653.                                             startPlayer();
  1654.                                         }
  1655.                                     }
  1656.                                     catch (Throwable e) {
  1657.                                         Log.d(LOG_TAG, "Exception - onAsyncCmdComplete : OPEN : " + e.getMessage() );
  1658.                                         e.printStackTrace();
  1659.                                     }
  1660.                                 }
  1661.                             });
  1662.  
  1663.                         }
  1664.                         else {
  1665.                             mHandler.post(new Runnable() {
  1666.                                 @Override
  1667.                                 public void run() {
  1668.                                     if( mCurrentPath != null )
  1669.                                         mToolbar.setTitle(NexFileIO.getContentTitle(mCurrentPath));
  1670.                                 }
  1671.                             });
  1672.                             onError(mp, NexErrorCode.fromIntegerValue(result));
  1673.                         }
  1674.                         break;
  1675.                     case NexPlayer.NEXPLAYER_ASYNC_CMD_OPEN_STORE_STREAM :
  1676.                         Log.d(LOG_TAG, "onAsyncCmdComplete : OPEN STORE STREAM");
  1677.                         clearBufferStatus();
  1678.                         mPlayerState = PLAYER_FLOW_STATE.BEGINNING_OF_COMPLETE;
  1679.                         mIsEnginOpen = true;
  1680.  
  1681.                         if(result == 0) {
  1682.                             mHandler.post(new Runnable() {
  1683.                                 @Override
  1684.                                 public void run() {
  1685.                                     try {
  1686.                                         if( mForeground ) {
  1687.                                             startPlayer();
  1688.                                         }
  1689.                                     }
  1690.                                     catch (Throwable e) {
  1691.                                         Log.d(LOG_TAG, "Exception - onAsyncCmdComplete : OPEN STORE STREAM: " + e.getMessage() );
  1692.                                         e.printStackTrace();
  1693.                                     }
  1694.                                 }
  1695.                             });
  1696.  
  1697.                         }
  1698.                         else {
  1699.                             mHandler.post(new Runnable() {
  1700.                                 @Override
  1701.                                 public void run() {
  1702.                                     if( mCurrentPath != null )
  1703.                                         mToolbar.setTitle(NexFileIO.getContentTitle(mCurrentPath));
  1704.                                 }
  1705.                             });
  1706.                             onError(mp, NexErrorCode.fromIntegerValue(result));
  1707.                         }
  1708.                         break;
  1709.                     case NexPlayer.NEXPLAYER_ASYNC_CMD_START_LOCAL:
  1710.                     case NexPlayer.NEXPLAYER_ASYNC_CMD_START_STREAMING:
  1711.                         Log.d(LOG_TAG, "onAsyncCmdComplete : START");
  1712.  
  1713.  
  1714.                         mPlayerState = PLAYER_FLOW_STATE.BEGINNING_OF_COMPLETE;
  1715.  
  1716.                         if(result == 0) {
  1717.                             if(mIsStreaming) {
  1718.                                 NxbInfo info = NxbInfo.getNxbInfo(mNxbWholeList, mCurrentPath, mCurrentPosition);
  1719.  
  1720.                                 if( PlaybackHistory.isExist(NexPlayerSample.this, info) ) {
  1721.                                     PlaybackHistory.updateHistory(NexPlayerSample.this, info);
  1722.                                 } else {
  1723.                                     PlaybackHistory.addHistory(NexPlayerSample.this, info);
  1724.                                 }
  1725.                             }
  1726.  
  1727.                             mHandler.post(new Runnable() {
  1728.                                 @SuppressLint("NewApi")
  1729.                                 @Override
  1730.                                 public void run() {
  1731.                                     mPlayPauseButton.setImageResource(android.R.drawable.ic_media_pause);
  1732.  
  1733.                                 }
  1734.                             });
  1735.  
  1736.                             mHandler.postDelayed(updateStatisticsThread, 1000);
  1737.                         }
  1738.                         else {
  1739.                             onError(mp, NexErrorCode.fromIntegerValue(result));
  1740.                         }
  1741.  
  1742.                         new java.util.Timer().schedule(
  1743.                                 new java.util.TimerTask() {
  1744.                                     @Override
  1745.                                     public void run() {
  1746.                                         requestAds(getString(R.string.ad_tag_url));
  1747.                                     }
  1748.                                 },
  1749.                                 5000
  1750.                         );
  1751.  
  1752.                         if( mPlayerState == PLAYER_FLOW_STATE.BEGINNING_OF_COMPLETE ) {
  1753.                             mPlayerState = PLAYER_FLOW_STATE.END_OF_COMPLETE;
  1754.                         }
  1755.                         break;
  1756.                     case NexPlayer.NEXPLAYER_ASYNC_CMD_PAUSE:
  1757.                         if( mIsLive && mForeground )
  1758.                             scheduleSeekableRangeTimeTask();
  1759.                         break;
  1760.                     case NexPlayer.NEXPLAYER_ASYNC_CMD_STOP:
  1761.                         Log.d(LOG_TAG, "onAsyncCmdComplete : STOP");
  1762.  
  1763.                         clearCaptionString();
  1764.  
  1765.                         cancelSeekableRangeTimer();
  1766.                         postProcessingForStopCmd();
  1767.  
  1768.                         break;
  1769.                     case NexPlayer.NEXPLAYER_ASYNC_CMD_SET_MEDIA_STREAM:
  1770.                         Log.d(LOG_TAG, "onAsyncCmdComplete : SET_MEDIA_STREAM");
  1771.  
  1772.                         mPlayerState = PLAYER_FLOW_STATE.BEGINNING_OF_COMPLETE;
  1773.                         mContentInfo = mNexPlayer.getContentInfo();
  1774.                         mNeedResume = false;
  1775.  
  1776.                         if(mPlayerState == PLAYER_FLOW_STATE.BEGINNING_OF_COMPLETE)
  1777.                             mPlayerState = PLAYER_FLOW_STATE.END_OF_COMPLETE;
  1778.  
  1779.                         if (NexPlayer.MEDIA_STREAM_TYPE_TEXT == param1)
  1780.                         {
  1781.                             clearCaptionString();
  1782.                         }
  1783.  
  1784.                         break;
  1785.                     case NexPlayer.NEXPLAYER_ASYNC_CMD_SEEK:
  1786.                         Log.d(LOG_TAG, "onAsyncCmdComplete : SEEK");
  1787.                         if( mSeekPoint > -1 ) {
  1788.                             if( mForeground )
  1789.                                 mNexPlayer.seek(mSeekPoint);
  1790.                             else
  1791.                                 mIsSeeking = false;
  1792.                             mSeekPoint = -1;
  1793.                         }
  1794.                         else if( mNexPlayer.getState() == NexPlayer.NEXPLAYER_STATE_PAUSE ) {
  1795.                             mSeekBar.setProgress(mNexPlayer.getCurrentPosition());
  1796.                             mIsSeeking = false;
  1797.                         } else {
  1798.                             if( mIsHeadsetRemoved || !mForeground ) {
  1799.                                 mHandler.post(new Runnable() {
  1800.  
  1801.                                     @Override
  1802.                                     public void run() {
  1803.                                         mNexPlayer.pause();
  1804.                                         mPlayPauseButton.setImageResource(android.R.drawable.ic_media_play);
  1805.                                         mIsHeadsetRemoved = false;
  1806.                                     }
  1807.                                 });
  1808.                             }
  1809.  
  1810.                             mIsSeeking = false;
  1811.                         }
  1812.  
  1813.                         clearCaptionString();
  1814.                         break;
  1815.                     case NexPlayer.NEXPLAYER_ASYNC_CMD_RESUME:
  1816.                         mHandler.post(new Runnable() {
  1817.  
  1818.                             @Override
  1819.                             public void run() {
  1820.                                 mPlayPauseButton.setImageResource(android.R.drawable.ic_media_pause);
  1821.                             }
  1822.                         });
  1823.  
  1824.                         cancelSeekableRangeTimer();
  1825.                         break;
  1826.                     case NexPlayer.NEXPLAYER_ASYNC_CMD_SETEXTSUBTITLE:
  1827.                         if( result == 0 ) {
  1828.                             mCurrentSubtitlePath = mTargetSubtitlePath;
  1829.  
  1830.                             mCaptionPainter.setCaptionType(mContentInfo.mCaptionType);
  1831.  
  1832.                             clearCaptionString();
  1833.                         } else {
  1834.                             mTargetSubtitlePath = mCurrentSubtitlePath;
  1835.                             showToastMsg(getString(R.string.invalid_subtitle_path));
  1836.                         }
  1837.  
  1838.                         break;
  1839.                 }
  1840.             }
  1841.  
  1842.  
  1843.             @Override
  1844.             public void onDynamicThumbnailData(NexPlayer mp, int width, int height, int cts, Object bitmap) {
  1845.                 super.onDynamicThumbnailData(mp, width, height, cts, bitmap);
  1846.  
  1847.                 if (!mSeekBar.isThumbnailArrayFull()) {
  1848.                     Bitmap bm = Bitmap.createBitmap(width, height, Config.RGB_565);
  1849.                     ByteBuffer buffer = (ByteBuffer) bitmap;
  1850.                     bm.copyPixelsFromBuffer(buffer.asIntBuffer());
  1851.                     mSeekBar.addDynamicThumbnailInfo(cts, bm);
  1852.                 }
  1853.             }
  1854.  
  1855.             @Override
  1856.             public void onDynamicThumbnailRecvEnd(NexPlayer mp) {
  1857.                 super.onDynamicThumbnailRecvEnd(mp);
  1858.  
  1859.                 mSeekBar.dynamicThumbnailRecvEnd();
  1860.             }
  1861.  
  1862.             @Override
  1863.             public byte[] onOfflineKeyRetrieveListener(NexPlayer mp) {
  1864.                 byte[] keyId = null;
  1865.  
  1866.                 if( mFileList != null ) {
  1867.                     File file = new File(mCurrentPath);
  1868.                     JSONObject obj = NexStoredInfoFileUtils.parseJSONObject(file);
  1869.                     if( obj != null ) {
  1870.                         try {
  1871.                             String sKeyId = obj.getString(NexStoredInfoFileUtils.STORED_INFO_KEY_OFFLINE_KEY_ID);
  1872.                             if(sKeyId != null)
  1873.                                 keyId = Base64.decode(sKeyId, Base64.DEFAULT);
  1874.                         } catch (JSONException e) {
  1875.                             e.printStackTrace();
  1876.                         }
  1877.                     }
  1878.                 }
  1879.                 return keyId;
  1880.             }
  1881.  
  1882.  
  1883.             @Override
  1884.             public void onOfflineKeyStoreListener(NexPlayer mp, byte[] keyId) {
  1885.             }
  1886.  
  1887.             @Override
  1888.             public void onEndOfContent(NexPlayer mp) {
  1889.                 getContentPath(mPrefData.mReplayMode);
  1890.  
  1891.                 mHandler.post(new Runnable() {
  1892.                     @Override
  1893.                     public void run() {
  1894.                         if( mFastPlay )
  1895.                             stopFastPlay();
  1896.                         mNexPlayer.stop();
  1897.                     }
  1898.                 });
  1899.             }
  1900.  
  1901.             @Override
  1902.             public void onTime(NexPlayer mp, int millisec) {
  1903.                 showProgressBar(millisec);
  1904.             }
  1905.  
  1906.             @Override
  1907.             public void onHTTPResponse(NexPlayer mp, String strResponse) {
  1908.                 playerSampleUtils.logHTTPResponse(strResponse);
  1909.             }
  1910.  
  1911.             @Override
  1912.             public void onHTTPRequest(NexPlayer mp, String strRequest) {
  1913.                 playerSampleUtils.logHTTPRequest(strRequest);
  1914.             }
  1915.  
  1916.             @Override
  1917.             public void onError(NexPlayer mp, NexErrorCode errorcode) {
  1918.                 Log.e(LOG_TAG, "onError: " + errorcode);
  1919.                 if (mPlayerState == PLAYER_FLOW_STATE.BEGINNING_OF_ONERROR)
  1920.                     return;
  1921.  
  1922.                 mPlayerState = PLAYER_FLOW_STATE.BEGINNING_OF_ONERROR;
  1923.  
  1924.                 if( errorcode == null ) {
  1925.                     showErrorStatus("onError : Unknown Error Occured with Invalid errorcode object");
  1926.                 }
  1927.                 else {
  1928.                     switch (errorcode.getCategory()) {
  1929.                         case API:
  1930.                         case BASE:
  1931.                         case NO_ERROR:
  1932.                         case INTERNAL:
  1933.                             showErrorStatus("An internal error occurred while attempting to open the media: "
  1934.                                     + errorcode.name());
  1935.                             break;
  1936.  
  1937.                         case AUTH:
  1938.                             showErrorStatus("You are not authorized to view this content, "
  1939.                                     + "or it was not possible to verify your authorization, "
  1940.                                     + "for the following reason:\n\n" + errorcode.getDesc());
  1941.                             break;
  1942.  
  1943.                         case CONTENT_ERROR:
  1944.                             showErrorStatus("The content cannot be played back, probably because of an error in "
  1945.                                     + "the format of the content (0x"
  1946.                                     + Integer.toHexString(errorcode.getIntegerCode())
  1947.                                     + ": " + errorcode.name() + ").");
  1948.                             break;
  1949.  
  1950.                         case NETWORK:
  1951.                             showErrorStatus("The content cannot be played back because of a "
  1952.                                     + "problem with the network.  This may be temporary, "
  1953.                                     + "and trying again later may resolve the problem.\n\n("
  1954.                                     + errorcode.getDesc() + ")");
  1955.                             break;
  1956.  
  1957.                         case NOT_SUPPORT:
  1958.                             showErrorStatus("The content cannot be played back because it uses a "
  1959.                                     + "feature which is not supported by NexPlayer.\n\n("
  1960.                                     + errorcode.getDesc() + ")");
  1961.                             break;
  1962.  
  1963.                         case GENERAL:
  1964.                             showErrorStatus("The content cannot be played back for the following reason:\n\n"
  1965.                                     + errorcode.getDesc());
  1966.                             break;
  1967.  
  1968.                         case PROTOCOL:
  1969.                             showErrorStatus("The content cannot be played back because of a "
  1970.                                     + "protocol error.  This may be due to a problem with "
  1971.                                     + "the network or a problem with the server you are "
  1972.                                     + "trying to access.  Trying again later may resolve "
  1973.                                     + "the problem.\n\n(" + errorcode.name() + ")" );
  1974.                             break;
  1975.                         case DOWNLOADER:
  1976.                             showErrorStatus("Download has the problem\n\n(" + errorcode.name() + ")" );
  1977.                             break;
  1978.  
  1979.                         case SYSTEM:
  1980.                             showErrorStatus("SYSTEM has the problem\n\n(" + errorcode.name() + ")" );
  1981.                             break;
  1982.                         case VMDRM:
  1983.                             showErrorStatus("VMDRM has the problem\n\n(" + errorcode.name() + ")" );
  1984.                             break;
  1985.                     }
  1986.                 }
  1987.  
  1988.                 mHandler.post(new Runnable() {
  1989.                     @Override
  1990.                     public void run() {
  1991.                         int state = mNexPlayer.getState();
  1992.  
  1993.                         if ( state == NexPlayer.NEXPLAYER_STATE_PLAY
  1994.                                 || state == NexPlayer.NEXPLAYER_STATE_PAUSE ) {
  1995.                             mNexPlayer.stop();
  1996.                         }
  1997.                         else if( state == NexPlayer.NEXPLAYER_STATE_STOP ){
  1998.                             closePlayer();
  1999.                             mPlayerState = PLAYER_FLOW_STATE.END_OF_ONERROR;
  2000.                         }
  2001.                         else if( state == NexPlayer.NEXPLAYER_STATE_CLOSED ) {
  2002.                             mPlayerState = PLAYER_FLOW_STATE.END_OF_ONERROR;
  2003.                         }
  2004.                     }
  2005.                 });
  2006.  
  2007.                 resetPlayerStatus(RESET_PLAYER_PROGRESS);
  2008.             }
  2009.  
  2010.             @Override
  2011.             public int onHTTPABRTrackChange(NexPlayer mp, int param1, int param2,
  2012.                                             int param3) {
  2013.                 int targetBW;
  2014.                 Log.d(LOG_TAG, "onHTTPABRTrackChange is called! Current BW: " + param1 + ", Current Track: " + param2 + ", Next Track: " + param3);
  2015.                 targetBW = param3; // Do not change the target BW.
  2016.                 Log.d(LOG_TAG, "target BW is " + targetBW);
  2017.                 return targetBW;
  2018.             }
  2019.  
  2020.             @Override
  2021.             public void onDataInactivityTimeOut(NexPlayer mp) {
  2022.                 onError(mp, NexErrorCode.DATA_INACTIVITY_TIMEOUT);
  2023.             }
  2024.  
  2025.             @Override
  2026.             public void onBufferingBegin(NexPlayer mp) {
  2027.                 mIsBuffering = true;
  2028.                 showBufferStatus(getResources().getString(R.string.buffer_start));
  2029.                 enableUIControls(false);
  2030.             }
  2031.  
  2032.             @Override
  2033.             public void onBufferingEnd(NexPlayer mp) {
  2034.                 mIsBuffering = false;
  2035.                 clearBufferStatus();
  2036.                 enableUIControls(true);
  2037.  
  2038.                 if(mSeekPoint > -1) {
  2039.                     if( mForeground )
  2040.                         mNexPlayer.seek(mSeekPoint);
  2041.                     else
  2042.                         mIsSeeking = false;
  2043.                     mSeekPoint = -1;
  2044.                 }
  2045.             }
  2046.  
  2047.             @Override
  2048.             public void onBuffering(NexPlayer mp, int progress_in_percent) {
  2049.                 showBufferStatus(getResources().getString(R.string.buffer_ing) +
  2050.                         progress_in_percent + getResources().getString(R.string.buffer_percent));
  2051.             }
  2052.  
  2053.             @Override
  2054.             public void onAudioRenderCreate(NexPlayer mp, int samplingRate, int channelNum) {
  2055.                 Log.d(LOG_TAG, "onAudioRenderCreate");
  2056.                 mAudioInitEnd = true;
  2057.             }
  2058.  
  2059.             @Override
  2060.             public void onVideoRenderCreate(NexPlayer mp, int width, int height,
  2061.                                             Object rgbBuffer) {
  2062.                 Log.d(LOG_TAG, "onVideoRenderCreate");
  2063.             }
  2064.  
  2065.             @Override
  2066.             public void onVideoRenderCapture(NexPlayer mp, int width, int height,
  2067.                                              int pixelbyte, Object rgbBuffer) {
  2068.                 final Bitmap thumbnailBitmap;
  2069.                 Bitmap bitmap = Bitmap.createBitmap(width, height, pixelbyte == 2 ? Config.RGB_565 : Config.ARGB_8888);
  2070.                 ByteBuffer RGBBuffer = (ByteBuffer) rgbBuffer;
  2071.  
  2072.                 if (RGBBuffer.capacity() > 0) {
  2073.                     RGBBuffer.asIntBuffer();
  2074.                     bitmap.copyPixelsFromBuffer(RGBBuffer);
  2075.  
  2076.                     if (bitmap != null) {
  2077.                         thumbnailBitmap = Bitmap.createScaledBitmap(
  2078.                                 (Bitmap) bitmap, 100, 75, true);
  2079.                         bitmap.recycle();
  2080.  
  2081.                         mHandler.post(new Runnable() {
  2082.                             public void run() {
  2083.                                 mThumbnailView.setImageBitmap(thumbnailBitmap);
  2084.                                 mThumbnailView.setEnabled(true);
  2085.                                 mThumbnailView.setVisibility(View.VISIBLE);
  2086.                                 mThumbnailView.requestLayout();
  2087.                             }
  2088.                         });
  2089.  
  2090.                         Timer timer = new Timer();
  2091.                         timer.schedule(new TimerTask() {
  2092.                             public void run() {
  2093.                                 mHandler.post(new Runnable() {
  2094.                                     public void run() {
  2095.                                         mThumbnailView.setVisibility(View.INVISIBLE);
  2096.                                     }
  2097.                                 });
  2098.                             }
  2099.                         }, 5000);
  2100.                     }
  2101.                 }
  2102.                 else {
  2103.                     mHandler.post(new Runnable() {
  2104.                         public void run() {
  2105.                             mThumbnailView.setVisibility(View.VISIBLE);
  2106.                             mThumbnailView.requestLayout();
  2107.                         }
  2108.                     });
  2109.                 }
  2110.             }
  2111.  
  2112.             @Override
  2113.             public void onTextRenderRender(NexPlayer mp, int trackIndex, NexClosedCaption textInfo) {
  2114.                 mCaptionPainter.setDataSource(textInfo);
  2115.                 mHandler.post(new Runnable() {
  2116.                     public void run() {
  2117.                         mCaptionPainter.invalidate();
  2118.                     }
  2119.                 });
  2120.  
  2121.             }
  2122.  
  2123.             @Override
  2124.             public void onTimedMetaRenderRender(NexPlayer mp,
  2125.                                                 final NexID3TagInformation TimedMeta) {
  2126.                 mHandler.post(new Runnable() {
  2127.                     public void run() {
  2128.                         try {
  2129.                             NexID3TagText text = null;
  2130.                             String strInfo = "";
  2131.                             String str = "";
  2132.  
  2133.                             text = TimedMeta.getArtist();
  2134.                             if( text != null && text.getTextData() != null) {
  2135.                                 str = new String(text.getTextData(), 0,
  2136.                                         text.getTextData().length,getTextEncodingType(text.getEncodingType()));
  2137.                                 strInfo += str + "\n";
  2138.                             }
  2139.  
  2140.                             text = TimedMeta.getTitle();
  2141.                             if( text != null && text.getTextData() != null) {
  2142.                                 str = new String(text.getTextData(), 0,text.getTextData().length,
  2143.                                         getTextEncodingType(text.getEncodingType()));
  2144.                                 strInfo += str + "\n";
  2145.                             }
  2146.  
  2147.                             text = TimedMeta.getAlbum();
  2148.                             if(text != null &&  text.getTextData() != null) {
  2149.                                 str = new String(text.getTextData(), 0, text.getTextData().length,
  2150.                                         getTextEncodingType(text.getEncodingType()));
  2151.                                 strInfo += str;
  2152.                             }
  2153.  
  2154.                             text = TimedMeta.getLyric();
  2155.                             if (text != null)  {
  2156.                                 str = new String(
  2157.                                         text.getTextData(), 0, text.getTextData().length,
  2158.                                         getTextEncodingType(text.getEncodingType()));
  2159.                                 strInfo += str;
  2160.  
  2161.                                 mLyricTextView.setText(strInfo);
  2162.                             }
  2163.                             else  {
  2164.                                 mLyricTextView.setText(strInfo);
  2165.                             }
  2166.  
  2167.                             setTimeMetaImage(TimedMeta);
  2168.                             text = TimedMeta.getPrivateFrame();
  2169.  
  2170.                             if (null != text)
  2171.                             {
  2172.                                 String strPrivateFrame = new String(
  2173.                                         text.getTextData(), 0, text.getTextData().length,
  2174.                                         getTextEncodingType(text.getEncodingType()));
  2175.  
  2176.                                 Log.d(LOG_TAG, "TimedMeta PRIVATE FRAME: " + strPrivateFrame);
  2177.                             }
  2178.  
  2179.                             text = TimedMeta.getText();
  2180.                             String strTextFrame;
  2181.  
  2182.                             if( text != null) {
  2183.                                 strTextFrame = new String(
  2184.                                         text.getTextData(), 0, text.getTextData().length,
  2185.                                         getTextEncodingType(text.getEncodingType()));
  2186.                                 mTimedMetaTextView.setText(strTextFrame);
  2187.                                 Log.d(LOG_TAG, "TimedMeta<1>: " + strTextFrame);
  2188.                             }
  2189.  
  2190.                             ArrayList<NexID3TagText> arrExtraData = TimedMeta.getArrExtraData();
  2191.  
  2192.                             String str1 = "";
  2193.                             String str2 = "";
  2194.  
  2195.                             if (arrExtraData != null) {
  2196.                                 for (int i = 0; i < arrExtraData.size(); ++i) {
  2197.                                     NexID3TagText ID3ExtraData = arrExtraData.get(i);
  2198.                                     str1 = new String(ID3ExtraData.getTextData(), 0, ID3ExtraData.getTextData().length,
  2199.                                             getTextEncodingType(ID3ExtraData.getEncodingType()));
  2200.  
  2201.                                     str2 = new String(ID3ExtraData.getExtraDataID(), 0, ID3ExtraData.getExtraDataID().length,
  2202.                                             getTextEncodingType(ID3ExtraData.getEncodingType()));
  2203.  
  2204.                                     if (null != str1 && null != str2) {
  2205.                                         final String strText = String.format("getExtraDataID : " + str2 + " getExtraData : " + str1);
  2206.  
  2207.                                         if (null != mTimedMetaTextView) {
  2208.                                             mHandler.post(new Runnable() {
  2209.                                                 @Override
  2210.                                                 public void run() {
  2211.                                                     mTimedMetaTextView.setText(strText);
  2212.                                                     Log.d(LOG_TAG, "TimedMeta<2>: " + strText);
  2213.                                                 }
  2214.                                             });
  2215.                                         }
  2216.                                     }
  2217.                                 }
  2218.                             }
  2219.  
  2220.                         }
  2221.                         catch (Throwable e) {
  2222.                             Log.d(LOG_TAG, "Exception - onTimedMetaRenderRender() : " + e.getMessage() );
  2223.                         }
  2224.                     }
  2225.                 });
  2226.             }
  2227.  
  2228.             @Override
  2229.             public void onStatusReport(NexPlayer mp, int msg, int param1) {
  2230.                 Log.d(LOG_TAG, "onStatusReport msg : " + msg + " , param1 : " + param1);
  2231.  
  2232.                 if (msg == NexPlayer.NEXPLAYER_STATUS_REPORT_CONTENT_INFO_UPDATED) {
  2233.                     mContentInfo = mNexPlayer.getContentInfo();
  2234.                     if( mContentInfoDialog != null )
  2235.                         mContentInfoDialog.setContentInfo(mContentInfo);
  2236.                     mHandler.post(new Runnable() {
  2237.                         @Override
  2238.                         public void run() {
  2239.                             String text = "Track : " + NexContentInfoExtractor.getCurrTrackID(NexPlayer.MEDIA_STREAM_TYPE_VIDEO, mContentInfo);
  2240.                             mTrackView.setText(text);
  2241.                         }
  2242.                     });
  2243.  
  2244.                     if(!mIsLive) {
  2245.                         mHandler.post(new Runnable() {
  2246.  
  2247.                             @Override
  2248.                             public void run() {
  2249.                                 mSeekBar.setMax(mContentInfo.mMediaDuration);
  2250.                                 mSeekBar.setDurationTimeText(mContentInfo.mMediaDuration);
  2251.                             }
  2252.                         });
  2253.                     }
  2254.  
  2255.                     if(mContentInfo.mMediaType == AUDIO_ONLY && mAudioInitEnd) {
  2256.                         mHandler.post(new Runnable() {
  2257.                             public void run() {
  2258.                                 mImageView.setVisibility(View.VISIBLE);
  2259.                                 mImageView.requestLayout();
  2260.                             }
  2261.                         });
  2262.                     }
  2263.                     else if (mContentInfo.mMediaType == AUDIO_VIDEO && mAudioInitEnd) {
  2264.                         boolean videoInitEnd = mVideoView.isInitialized();
  2265.  
  2266.                         if (mAudioInitEnd &&
  2267.                                 (videoInitEnd || mContentInfo.mCurrVideoStreamID == NexPlayer.MEDIA_STREAM_DISABLE_ID) ) {
  2268.                             mHandler.post(new Runnable() {
  2269.                                 public void run() {
  2270.                                     mImageView.setVisibility(View.INVISIBLE);
  2271.                                     mImageView.requestLayout();
  2272.                                 }
  2273.                             });
  2274.                         }
  2275.                     }
  2276.                     else if (mContentInfo.mMediaType == VIDEO_ONLY) {
  2277.                         boolean videoInitEnd = false;
  2278.                         videoInitEnd = mVideoView.isInitialized();
  2279.  
  2280.                         if (videoInitEnd) {
  2281.                             mHandler.post(new Runnable() {
  2282.                                 public void run() {
  2283.                                     mImageView.setVisibility(View.INVISIBLE);
  2284.                                     mImageView.requestLayout();
  2285.                                 }
  2286.                             });
  2287.                         }
  2288.  
  2289.                     }
  2290.                 }
  2291.                 else if (msg == NexPlayer.NEXPLAYER_STATUS_REPORT_STREAM_RECV_PAUSE) {
  2292.                     Log.d(LOG_TAG, "Stream Receive Pause.");
  2293.                 }
  2294.                 else if (msg == NexPlayer.NEXPLAYER_STATUS_REPORT_STREAM_RECV_RESUME) {
  2295.                     Log.d(LOG_TAG, "Stream Receive Resume.");
  2296.                 }
  2297.             }
  2298.  
  2299.             @Override
  2300.             public void onDownloaderError(NexPlayer mp, int msg, int param1) {
  2301.                 Log.d(LOG_TAG, "onDownloaderError MSG : " + msg + " param1 : " + param1 + " mDownloaderState : " + mDownloaderState);
  2302.  
  2303.                 onError(mp, NexErrorCode.fromIntegerValue(msg));
  2304.  
  2305.                 if( mDownloaderState == NexPlayer.NEXDOWNLOADER_STATE_DOWNLOAD ) {
  2306.                     mNexPlayer.DownloaderStop();
  2307.                 }
  2308.                 else if( mDownloaderState == NexPlayer.NEXDOWNLOADER_STATE_STOP ) {
  2309.                     mNexPlayer.DownloaderClose();
  2310.                 }
  2311.                 mStrExternalPDFile = null;
  2312.                 mTotalSize = 0;
  2313.             }
  2314.  
  2315.             @Override
  2316.             public void onDownloaderAsyncCmdComplete(NexPlayer mp, int msg, int result,
  2317.                                                      int param2) {
  2318.                 Log.d(LOG_TAG, "onDownloaderAsyncCmdComplete msg : " + msg + " result : " + result);
  2319.  
  2320.                 switch( msg) {
  2321.                     case NexPlayer.NEXDOWNLOADER_ASYNC_CMD_OPEN:
  2322.                         if(result == 0) {
  2323.                             Log.d(LOG_TAG, "onDownloaderAsyncCmdComplete : OPEN");
  2324.                             mNexPlayer.DownloaderStart();
  2325.                         } else {
  2326.                             NexPlayer.NexErrorCode errorCode = NexErrorCode.fromIntegerValue(result);
  2327.  
  2328.                             if(NexErrorCode.HTTPDOWNLOADER_ERROR_ALREADY_DOWNLOADED.equals(errorCode)) {
  2329.  
  2330.                                 mHandler.post(new Runnable() {
  2331.                                     @Override
  2332.                                     public void run() {
  2333.                                         int result = mNexPlayer.open(
  2334.                                                 mStrExternalPDFile,
  2335.                                                 null, // JDKIM 2010/08/18
  2336.                                                 null,
  2337.                                                 NexPlayer.NEXPLAYER_SOURCE_TYPE_LOCAL_NORMAL,
  2338.                                                 NexPlayer.NEXPLAYER_TRANSPORT_TYPE_TCP);
  2339.  
  2340.                                         if( result != 0 ) {
  2341.                                             onError(mNexPlayer, NexErrorCode.fromIntegerValue(result));
  2342.                                         }
  2343.  
  2344.                                         mCurrentPath = mStrExternalPDFile;
  2345.                                         mStrExternalPDFile = null;
  2346.                                         mIsStreaming = false;
  2347.                                     }
  2348.                                 });
  2349.                             }
  2350.                             else {
  2351.                                 onError(mp, NexErrorCode.fromIntegerValue(result));
  2352.                                 mStrExternalPDFile = null;
  2353.                             }
  2354.                         }
  2355.  
  2356.                         break;
  2357.  
  2358.                     case NexPlayer.NEXDOWNLOADER_ASYNC_CMD_START:
  2359.                         Log.d(LOG_TAG, "onDownloaderAsyncCmdComplete : START");
  2360.                         if(result != 0) {
  2361.                             onError(mp, NexErrorCode.fromIntegerValue(result));
  2362.                             mNexPlayer.DownloaderClose();
  2363.                         }
  2364.                         break;
  2365.  
  2366.                     case NexPlayer.NEXDOWNLOADER_ASYNC_CMD_STOP:
  2367.                         Log.d(LOG_TAG, "onDownloaderAsyncCmdComplete : STOP");
  2368.                         mNexPlayer.DownloaderClose();
  2369.                         mTotalSize = 0;
  2370.                         break;
  2371.  
  2372.                     case NexPlayer.NEXDOWNLOADER_ASYNC_CMD_CLOSE:
  2373.                         Log.d(LOG_TAG, "onDownloaderAsyncCmdComplete : CLOSE");
  2374.                         break;
  2375.  
  2376.                     default:
  2377.                         break;
  2378.                 }
  2379.             }
  2380.  
  2381.             @Override
  2382.             public void onDownloaderEventBegin(NexPlayer mp, int param1, int param2) {
  2383.                 Log.d(LOG_TAG, "onDownloaderEventBegin " +" size : + " + param2);
  2384.                 mTotalSize = param2;
  2385.                 mHandler.post(new Runnable() {
  2386.  
  2387.                     @Override
  2388.                     public void run() {
  2389.                         if( mCurrentPath != null ) {
  2390.                             int result = mNexPlayer.open(
  2391.                                     mCurrentPath,
  2392.                                     null, // JDKIM 2010/08/18
  2393.                                     mStrExternalPDFile,
  2394.                                     NexPlayer.NEXPLAYER_SOURCE_TYPE_STREAMING,
  2395.                                     NexPlayer.NEXPLAYER_TRANSPORT_TYPE_TCP);
  2396.  
  2397.                             if( result != 0 ) {
  2398.                                 onError(mNexPlayer, NexErrorCode.fromIntegerValue(result));
  2399.                             }
  2400.                         }
  2401.                     }
  2402.                 });
  2403.             }
  2404.  
  2405.             @Override
  2406.             public void onDownloaderEventProgress(NexPlayer mp, int param1, int param2,
  2407.                                                   long param3, long param4) {
  2408.                 mTotalSize = param4;
  2409.                 mNexPlayer.SetExternalPDFileDownloadSize(param3, param4);
  2410.             }
  2411.  
  2412.             @Override
  2413.             public void onDownloaderEventComplete(NexPlayer mp, int param1) {
  2414.                 Log.d(LOG_TAG, "onDownloaderEventComplete ");
  2415.                 mNexPlayer.DownloaderStop();
  2416.                 mNexPlayer.SetExternalPDFileDownloadSize(mTotalSize, mTotalSize);
  2417.             }
  2418.  
  2419.             @Override
  2420.             public void onDownloaderEventState(NexPlayer mp, int param1, int param2) {
  2421.                 mDownloaderState = param2;
  2422.             }
  2423.  
  2424.             @Override
  2425.             public void onPictureTimingInfo(NexPlayer mp,
  2426.                                             NexPictureTimingInfo[] arrPictureTimingInfo) {
  2427.             }
  2428.         };
  2429.  
  2430.         mNexPlayer.addEventReceiver(mEventReceiver);
  2431.     }
  2432.    
  2433.     private void setProperties() {
  2434.         mNexPlayer.setProperty(NexPlayer.NexProperty.MAX_BW, mPrefData.mMaxBandWidth * BANDWIDTH_KBPS);
  2435.         mNexPlayer.setProperty(NexPlayer.NexProperty.MIN_BW, mPrefData.mMinBandWidth * BANDWIDTH_KBPS);
  2436.         mNexPlayer.setProperty(NexProperty.TIMESTAMP_DIFFERENCE_VDISP_WAIT, mPrefData.mVideoDisplayWait);
  2437.         mNexPlayer.setProperty(NexProperty.TIMESTAMP_DIFFERENCE_VDISP_SKIP, mPrefData.mVideoDisplaySkip);
  2438.         mNexPlayer.setProperty(NexProperty.AV_SYNC_OFFSET, (int) (mPrefData.mAVSyncOffset * 1000));
  2439.         mNexPlayer.setProperty(NexProperty.PREFER_LANGUAGE_AUDIO, mPrefData.mPrefLanguageAudio);
  2440.         mNexPlayer.setProperty(NexProperty.PREFER_LANGUAGE_TEXT, mPrefData.mPrefLanguageText);
  2441.         mNexPlayer.setProperty(NexProperty.PREFER_BANDWIDTH, 100);
  2442.         mNexPlayer.setProperty(NexProperty.PREFER_AV, 1);
  2443.         mNexPlayer.setProperty(NexProperty.START_NEARESTBW, mPrefData.mStartNearestBW);
  2444.         mNexPlayer.setProperty(NexProperty.SUBTITLE_TEMP_PATH, mPrefData.mSubtitleDownloadPath);
  2445.         mNexPlayer.setProperty(NexProperty.ENABLE_ID3_TTML, mPrefData.mEnableID3TTML ? 1 : 0);
  2446.  
  2447.         mNexPlayer.setDebugLogs( mPrefData.mCodecLogLevel, mPrefData.mRendererLogLevel, mPrefData.mProtoclLogLevel );
  2448.  
  2449.         changeDolbyEnhancementGainValue(mPrefData.mDolbyEnhancementGain);
  2450.         changeDolbyPostProcessingValue(mPrefData.mEnableDolbyPostProcessing);
  2451.         changeDolbyEndPointValue(mPrefData.mDolbyEndPoint);
  2452.        
  2453.         if( !mPrefData.mEnableAudioOnlyTrack )
  2454.             mNexPlayer.setProperty(NexProperty.ENABLE_AUDIOONLY_TRACK, 0);
  2455.        
  2456.         if( mPrefData.mIgnoreTextmode )
  2457.             mNexPlayer.setProperty(NexProperty.IGNORE_CEA608_TEXTMODE_COMMAND, 1);
  2458.        
  2459.         if( mPrefData.mEnableWebVTT == false )
  2460.             mNexPlayer.setProperty(NexProperty.ENABLE_WEBVTT, 0);
  2461.        
  2462.         if( mPrefData.mWebVTTWaitOpen == false )
  2463.             mNexPlayer.setProperty(NexProperty.WEBVTT_WAITOPEN, 0);
  2464.        
  2465.         if( mPrefData.mHLSRunModeStable == true )
  2466.             mNexPlayer.setProperty(NexProperty.HLS_RUNMODE, 1);
  2467.        
  2468.         if( mPrefData.mCaptionMode == 1 )
  2469.             mNexPlayer.setProperty(NexProperty.ENABLE_CEA708, 1);
  2470.        
  2471.         if ( mPrefData.mUseEyePleaser == false )
  2472.             mNexPlayer.setProperty(NexProperty.SUPPORT_EYE_PLEASER, 0);
  2473.        
  2474.         if( mPrefData.mIsTrackdownEnabled ) {
  2475.             mNexPlayer.setProperty(NexProperty.ENABLE_TRACKDOWN, 1);
  2476.             mNexPlayer.setProperty(NexProperty.TRACKDOWN_VIDEO_RATIO, (int)mPrefData.mTrackdownThreshold);         
  2477.         }
  2478.        
  2479.         if( mPrefData.mBufferTime != 0 ) {
  2480.             mNexPlayer.setProperty(NexProperty.INITIAL_BUFFERING_DURATION, (int) (mPrefData.mBufferTime * 1000));
  2481.             mNexPlayer.setProperty(NexProperty.RE_BUFFERING_DURATION, (int) (mPrefData.mBufferTime * 1000));
  2482.         }
  2483.         if( mPrefData.mTSDumpEnable ) {
  2484.             File dump = new File(mPrefData.mTSDumpPath);
  2485.            
  2486.             if( !dump.exists() ) {
  2487.                 dump.mkdir();
  2488.             }
  2489.             mNexPlayer.setProperties(36,0x12);
  2490.             mNexPlayer.setProperties(37, mPrefData.mTSDumpPath);
  2491.         }
  2492.  
  2493.            
  2494.         if( mPrefData.mPCMDumpEnable ) {
  2495.             String path = mPrefData.mPCMDumpPath + NexFileIO.getContentTitle(mCurrentPath) + "/";
  2496.             File dump = new File(path);
  2497.             if (!dump.exists()) {
  2498.                 dump.mkdirs();
  2499.             }
  2500.             mNexPlayer.setProperties(NEXPLAYER_PROPERTY_DATA_DUMP_SUB_PATH, path);
  2501.         }
  2502.  
  2503.  
  2504.         //For NexHD
  2505.         /*
  2506.         {
  2507.             NexHDManager manager = new NexHDManager();
  2508.             manager.initManager(strEnginePath);
  2509.         }
  2510.         */
  2511.        
  2512.         if( mPrefData.mEnableClientSideTimeShift)
  2513.         {
  2514.             Log.d(LOG_TAG,"Enalbed Client-Side TimeShift. BufferSize(" + mPrefData.mTimeShiftMaxBufferSize + " MB), BufferDuration("+mPrefData.mTimeShiftMaxBufferDuration+" Min)");
  2515.             String strTSPath = "/sdcard/TimeShift/";
  2516.             File tsPath = new File(strTSPath);
  2517.             if(tsPath.isDirectory() == false)
  2518.             {
  2519.                 tsPath.mkdirs();
  2520.             }
  2521.             mNexPlayer.setClientTimeShift(  mPrefData.mEnableClientSideTimeShift,
  2522.                                             strTSPath,
  2523.                                             mPrefData.mTimeShiftMaxBufferSize,
  2524.                                             mPrefData.mTimeShiftMaxBufferDuration);
  2525.         }
  2526.         else
  2527.         {
  2528.             Log.d(LOG_TAG, "Disable Client-Side TimeShift.");
  2529.             mNexPlayer.setClientTimeShift(mPrefData.mEnableClientSideTimeShift, null, 0, 0);           
  2530.         }
  2531.     }
  2532.  
  2533.     private void setCustomNetAddrTable()
  2534.     {
  2535.         NexNetAddrTable table = new NexNetAddrTable();
  2536.         table.addEntry("localhost", "127.0.0.1");
  2537.         mNexPlayer.setNetAddrTable(table, NexNetAddrTable.NETADDR_TABLE_FALLBACK);
  2538.     }
  2539.  
  2540.  
  2541.     private void showToastMsg(final String msg) {
  2542.         mHandler.post(new Runnable() {
  2543.             @Override
  2544.             public void run() {
  2545.                 Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
  2546.             }
  2547.         });
  2548.     }
  2549.  
  2550.     private void setVolume() {
  2551.         mNexPlayer.setVolume((mVolume/10)); //Range : 0 ~1.0
  2552.     }
  2553.    
  2554.     private NexPlayerSampleExtensionLoader.ISampleExtension mSampleExtension = null;
  2555.     private synchronized NexPlayerSampleExtensionLoader.ISampleExtension getSampleExtension() {
  2556.         if ( mSampleExtension == null ) {
  2557.             Context context = NexPlayerSample.this.getApplicationContext();
  2558.             mSampleExtension = NexPlayerSampleExtensionLoader.loadExtension(mNexPlayer, context);
  2559.             mSampleExtension.setListener(new NexPlayerSampleExtensionLoader.ISampleExtensionListener() {
  2560.                 public void errorStatus(NexErrorCode errorCode, String message) {
  2561.                     showErrorStatus(message + '(' + errorCode.getDesc() +')');
  2562.                 }
  2563.             });
  2564.         }
  2565.         return mSampleExtension;
  2566.     }
  2567.    
  2568.     boolean shouldStartPlay() {
  2569.         return getSampleExtension().shouldStartPlay(mPrefData,
  2570.                 NxbInfo.getNxbInfo(mNxbWholeList, mCurrentPath, mCurrentPosition));
  2571.     }
  2572.  
  2573.     private void startPlay() {
  2574.         if (mNexPlayer.getState() == NexPlayer.NEXPLAYER_STATE_STOP || mPlayerState == PLAYER_FLOW_STATE.START_PLAY )
  2575.         {
  2576.             closePlayer();
  2577.         }
  2578.         mCurrentPath = String.valueOf(mCurrentPath);
  2579.  
  2580.         boolean enableRetrieving = false;
  2581.         if( !mCurrentPath.endsWith(NexFileIO.STORE_INFO_EXTENSION) ) {
  2582.             if (!shouldStartPlay()) {
  2583.                 return;
  2584.             }
  2585.         } else {
  2586.             enableRetrieving = true;
  2587.         }
  2588.         mPlayerState = PLAYER_FLOW_STATE.START_PLAY;
  2589.         mNexPlayer.setOfflineMode(false, enableRetrieving);
  2590.  
  2591.         if ( mCurrentPath.length() == 0 ) {
  2592.             showErrorStatus("Media URL/path not set for playback");
  2593.             return;
  2594.         }
  2595.         showBufferStatus(getResources().getString(R.string.buffer_open));
  2596.         mFastPlay = false;
  2597.  
  2598.         int sourceType = NexPlayer.NEXPLAYER_SOURCE_TYPE_LOCAL_NORMAL;
  2599.         boolean end = (mCurrentPath.endsWith("ismv") || mCurrentPath.endsWith("mp4"));
  2600.         boolean start = (mCurrentPath.startsWith("http") || mCurrentPath.startsWith("https"));
  2601.  
  2602.         if( mPrefData.mUseExternalPD && end && start ) {
  2603.             String parentPath = Environment.getExternalStorageDirectory().getPath();
  2604.             mStrExternalPDFile = parentPath
  2605.                     + File.separator
  2606.                     + NexFileIO.getExternalFileName(mCurrentPath);
  2607.             mNexPlayer.DownloaderOpen(mCurrentPath, mStrExternalPDFile, null, 0, NexPlayer.NEXDOWNLOADER_OPEN_TYPE_APPEND);
  2608.         } else {
  2609.             if( mIsStreaming ) {
  2610.                 sourceType = NexPlayer.NEXPLAYER_SOURCE_TYPE_STREAMING;
  2611.                 enableDynamicThumbnail();
  2612.             }
  2613.  
  2614.             if( mPrefData.mEnableStatisticsMonitor) {
  2615.                 mStatisticsMonitor = new NexStatisticsMonitor(mNexPlayer);
  2616.                 mStatisticsMonitor.setDuration(STATISTICS_GENERAL, 5);
  2617.                 setStatisticListener();
  2618.             }
  2619.  
  2620.  
  2621.             int result = mNexPlayer.open(mCurrentPath, null, null, sourceType,
  2622.                     mPrefData.mUseUDP ? NexPlayer.NEXPLAYER_TRANSPORT_TYPE_UDP :
  2623.                             NexPlayer.NEXPLAYER_TRANSPORT_TYPE_TCP);
  2624.             if( result != 0 ) {
  2625.                 mEventReceiver.onError(mNexPlayer, NexErrorCode.fromIntegerValue(result));
  2626.             }
  2627.  
  2628.         }
  2629.     }
  2630.  
  2631.     private void setStatisticListener() {
  2632.         mStatisticsListener = new NexStatisticsMonitor.IStatisticsListener() {
  2633.             @Override
  2634.             public void onUpdated(int statisticsType, HashMap<IStatistics, Object> map) {
  2635.                 mStatisticsDialog.onUpdated(statisticsType, map);
  2636.             }
  2637.         };
  2638.         mStatisticsMonitor.setListener(mStatisticsListener);
  2639.     }
  2640.  
  2641.  
  2642.     @Override
  2643.     public boolean onKeyDown(int keyCode, KeyEvent event) {
  2644.         Log.d(LOG_TAG, "onKeyDown keyCode : " + keyCode);
  2645.  
  2646.         if( mSeekBar.hasFocus() ) {
  2647.             if( keyCode == KeyEvent.KEYCODE_DPAD_CENTER ) {
  2648.                 if( mFastPlay )
  2649.                     stopFastPlay();
  2650.  
  2651.                 mIsSeeking = (mNexPlayer.seek(mSeekBar.getProgress()) == 0);
  2652.             }
  2653.         }
  2654.  
  2655.         return super.onKeyDown(keyCode, event);
  2656.     }
  2657.  
  2658.     private void showProgressBar(int millisec) {
  2659.         if( !mSeekBar.hasFocus() ) {
  2660.             if( mIsLive ) {
  2661.                 long[] seekableRange = mNexPlayer.getSeekableRangeInfo();
  2662.  
  2663.                 if( seekableRange == null ) {
  2664.                     mSeekBar.enableSeekBar(false);
  2665.                     mProgressBase = 0;
  2666.                 } else {
  2667.                     mSeekBar.enableSeekBar(true);
  2668.                     mProgressBase = (int)seekableRange[0];
  2669.                     int seekbarMaxLength = (int)seekableRange[1] - mProgressBase;
  2670.                     mSeekBar.setMax(seekbarMaxLength);
  2671.  
  2672.                     if(!mSeekBar.isTrackingTouch()) {
  2673.                         millisec = Math.min(millisec, (int)seekableRange[1]);
  2674.                         int progress = Math.max((millisec - mProgressBase), 0);
  2675.                         mSeekBar.setProgress(progress);
  2676.                         mSeekBar.setDurationTimeText((int)seekableRange[1]);
  2677.  
  2678.                         if( mContentInfo != null ) {
  2679.                             int streamType = mContentInfo.mMediaType == VIDEO_ONLY ? NexPlayer.MEDIA_STREAM_TYPE_VIDEO : NexPlayer.MEDIA_STREAM_TYPE_AUDIO;
  2680.                             mSeekBar.setSecondaryProgress(mNexPlayer.getBufferInfo(streamType, NexPlayer.NEXPLAYER_BUFINFO_INDEX_LASTCTS));
  2681.                         }
  2682.                     }
  2683.                 }
  2684.             } else {
  2685.                 int duration = mNexPlayer.getContentInfoInt(NexPlayer.CONTENT_INFO_INDEX_MEDIA_DURATION);
  2686.  
  2687.                 if(duration < millisec) {
  2688.                     duration = millisec;
  2689.                 }
  2690.  
  2691.                 mSeekBar.setMax(duration);
  2692.  
  2693.                 if(!mSeekBar.isTrackingTouch()) {
  2694.                     if(mSeekPoint < 0) {
  2695.                         mSeekBar.setProgress(millisec);
  2696.                     } else {
  2697.                         mSeekBar.setProgress(mSeekPoint);
  2698.                     }
  2699.                 }
  2700.  
  2701.                 if( mContentInfo != null ) {
  2702.                     int streamType = mContentInfo.mMediaType == VIDEO_ONLY ? NexPlayer.MEDIA_STREAM_TYPE_VIDEO : NexPlayer.MEDIA_STREAM_TYPE_AUDIO;
  2703.                     mExternalPDBufferDuration = mNexPlayer.getBufferInfo(streamType, NexPlayer.NEXPLAYER_BUFINFO_INDEX_LASTCTS);
  2704.                     mSeekBar.setSecondaryProgress(mExternalPDBufferDuration);
  2705.                 }
  2706.             }
  2707.         }
  2708.  
  2709.         mSeekBar.setKeyProgressIncrement(mPrefData.mSeekOffset * 1000);
  2710.         NexPlayer.PROGRAM_TIME pTime = new NexPlayer.PROGRAM_TIME();
  2711.         mNexPlayer.getProgramTime(pTime);
  2712.     }
  2713.  
  2714.    
  2715.     private void showErrorStatus(final String status) {
  2716.         mHandler.post(new Runnable() {
  2717.            
  2718.             @Override
  2719.             public void run() {
  2720.                 mErrorView.setText(status);
  2721.                 mErrorView.setVisibility(View.VISIBLE);
  2722.                 clearBufferStatus();
  2723.             }
  2724.         });
  2725.     }
  2726.    
  2727.     private void resetSeekStatus() {
  2728.         mIsBuffering = false;
  2729.         mIsSeeking = false;
  2730.         mSeekPoint = -1;
  2731.         mProgressBase = 0;
  2732.     }
  2733.    
  2734.     private void setDynamicThumbnailOption(NexContentInformation contentInfo) {
  2735.         if( mPrefData.mEnableDynamicThumbnail && contentInfo.mMediaDuration > 0 && (contentInfo.mSubSrcType == 6 || contentInfo.mSubSrcType == 5)) {
  2736.             mSeekBar.enableDynamicThumbnail(true);
  2737.             int intervalTime = contentInfo.mMediaDuration / mPrefData.mMaxThumbnailFrame;
  2738.             mSeekBar.setMaximumThumbnailFrame(mPrefData.mMaxThumbnailFrame);
  2739.             mSeekBar.setThumbnailSearchInterval(intervalTime);
  2740.             mNexPlayer.setOptionDynamicThumbnail(NexPlayer.OPTION_DYNAMIC_THUMBNAIL_INTERVAL, intervalTime, 0);
  2741.         }
  2742.     }
  2743.  
  2744.     private void scheduleSeekableRangeTimeTask() {
  2745.         mTimer = new Timer();
  2746.         UpdateSeekableRangeTimerTask timerTask = new UpdateSeekableRangeTimerTask();
  2747.         mTimer.schedule(timerTask, 1000, 1000);
  2748.     }
  2749.  
  2750.     private void cancelSeekableRangeTimer() {
  2751.         if( mTimer != null ) {
  2752.             mTimer.cancel();
  2753.             mTimer = null;
  2754.         }
  2755.     }
  2756.  
  2757.     private class UpdateSeekableRangeTimerTask extends TimerTask {
  2758.         @Override
  2759.         public void run() {
  2760.             Log.d(LOG_TAG, "updateSeekableRangeTimer run");
  2761.             showProgressBar(mNexPlayer.getCurrentPosition());
  2762.         }
  2763.     }
  2764.  
  2765.     private void getContentPath(int mode) {
  2766.         int newIndex = mCurrentPosition;
  2767.        
  2768.         switch(mode) {
  2769.         case REPLAY_MODE_NEXT:
  2770.             newIndex++;
  2771.             if( mFileList != null ) {
  2772.                 mIsStreaming = false;
  2773.  
  2774.                 newIndex = mPlayListUtil.getNextContentIndex(mFileList, newIndex);
  2775.                 if( newIndex != PlayListUtils.NOT_FOUND ) {
  2776.                     mCurrentPosition = newIndex;
  2777.                     mCurrentPath = mFileList.get(mCurrentPosition).getAbsolutePath();
  2778.                     mTargetSubtitlePath = NexFileIO.subtitlePathFromMediaPath(mCurrentPath);
  2779.                 }
  2780.             } else {
  2781.                 if( mNxbWholeList != null ) {
  2782.                     mIsStreaming = true;
  2783.  
  2784.                     if( mNxbWholeList.size() <= newIndex )
  2785.                         newIndex = 0;
  2786.                     mCurrentPosition = newIndex;
  2787.                     NxbInfo info = mNxbWholeList.get(mCurrentPosition);
  2788.                     mCurrentPath = info.getUrl();
  2789.  
  2790.                     mTargetSubtitlePath = getSubtitlePath(info, 0);
  2791.                     mCurrentExtraData =  getNxbExtraData();
  2792.                 }
  2793.  
  2794.                 mCurrentExtraData =  getNxbExtraData();
  2795.                 mTargetSubtitlePath = getFirstSubtitlePath();
  2796.             }
  2797.             mExistFollowingContentPath = true;
  2798.             break;
  2799.         case REPLAY_MODE_QUIT:
  2800.             mCurrentPath = null;
  2801.             break;
  2802.         case REPLAY_MODE_AGAIN:
  2803.             mExistFollowingContentPath = true;
  2804.             break;
  2805.         case REPLAY_MODE_PREVIOUS:
  2806.             newIndex--;
  2807.  
  2808.             if( mFileList != null ) {
  2809.                 mIsStreaming = false;
  2810.  
  2811.                 newIndex = mPlayListUtil.getPreviousContentIndex(mFileList, newIndex);
  2812.                 if( newIndex != PlayListUtils.NOT_FOUND ) {
  2813.                     mCurrentPosition = newIndex;
  2814.                     mCurrentPath = mFileList.get(mCurrentPosition).getAbsolutePath();
  2815.                     mTargetSubtitlePath = NexFileIO.subtitlePathFromMediaPath(mCurrentPath);
  2816.                 }
  2817.             } else if( mNxbWholeList != null ) {
  2818.                 mIsStreaming = true;
  2819.  
  2820.                 if( newIndex == -1 )
  2821.                     newIndex = mNxbWholeList.size() - 1;
  2822.                 mCurrentPosition = newIndex;
  2823.                 NxbInfo info = mNxbWholeList.get(mCurrentPosition);
  2824.                 mCurrentPath = info.getUrl();
  2825.  
  2826.                 mTargetSubtitlePath = getSubtitlePath(info, 0);
  2827.                 mCurrentExtraData =  getNxbExtraData();
  2828.             }
  2829.             mExistFollowingContentPath = true;
  2830.             break;
  2831.         }
  2832.     }
  2833.  
  2834.     private String getSubtitlePath(NxbInfo info, int index) {
  2835.         String path = null;
  2836.         if( info != null && info.getSubtitle().size() > index )
  2837.             path = info.getSubtitle().get(index);
  2838.         return path;
  2839.     }
  2840.  
  2841.     @Override
  2842.     protected void onNewIntent(Intent intent) {
  2843.         setIntent(intent);
  2844.         getIntentExtra();
  2845.  
  2846.         if(mCurrentPath != null && mNexPlayer != null) {
  2847.             int state = mNexPlayer.getState();
  2848.  
  2849.             if( state != NexPlayer.NEXPLAYER_STATE_STOP &&
  2850.                     state != NexPlayer.NEXPLAYER_STATE_NONE ) {
  2851.                 if (mFastPlay)
  2852.                     stopFastPlay();
  2853.  
  2854.                 if (mStrExternalPDFile != null)
  2855.                     stopDownload();
  2856.  
  2857.                 resetPlayerStatus(RESET_PLAYER_ALL);
  2858.  
  2859.                 if (state == NexPlayer.NEXPLAYER_STATE_CLOSED) {
  2860.                     startPlay();
  2861.                 } else if (state > NexPlayer.NEXPLAYER_STATE_STOP) {
  2862.                     mHaveToStartPlayer = true;
  2863.                     stopPlayer();
  2864.                 }
  2865.             }
  2866.         }
  2867.         super.onNewIntent(intent);
  2868.     }
  2869.  
  2870.     private void setAlbumImage() {
  2871.         NexID3TagPicture picture = null;
  2872.         if (mContentInfo.mID3Tag != null) {
  2873.             picture = mContentInfo.mID3Tag.getPicture();
  2874.             if(picture != null) {
  2875.                 Bitmap bm = BitmapFactory.decodeByteArray(picture.getPictureData(),0, picture.getPictureData().length);
  2876.                 if( bm != null ) {
  2877.                     mImageView.setImageBitmap(bm);
  2878.                 }
  2879.                 else {
  2880.                     mImageView.setImageResource(R.drawable.audio_skin2);
  2881.                 }
  2882.                 mImageView.setVisibility(View.VISIBLE);
  2883.             }
  2884.             else {
  2885.                 mImageView.setImageResource(R.drawable.audio_skin2);
  2886.                 mImageView.setVisibility(View.VISIBLE);
  2887.             }
  2888.         }
  2889.         else {
  2890.             mImageView.setImageResource(R.drawable.audio_skin2);
  2891.             mImageView.setVisibility(View.VISIBLE);
  2892.         }
  2893.     }
  2894.    
  2895.     private void setTimeMetaImage(NexID3TagInformation TimedMeta) {
  2896.         NexID3TagPicture picture = TimedMeta.getPicture();
  2897.         if( picture != null && picture.getPictureData() != null) {                 
  2898.             Bitmap bm = BitmapFactory.decodeByteArray(picture.getPictureData(),0, picture.getPictureData().length);
  2899.             mImageView.setImageBitmap(bm);
  2900.             mImageView.setBackgroundColor(Color.TRANSPARENT);
  2901.             mImageView.requestLayout();
  2902.         }
  2903.     }
  2904.    
  2905.     private void setLyric() {
  2906.         try {
  2907.             if (mContentInfo.mID3Tag != null) {
  2908.                 NexID3TagText text = null;
  2909.                 String strInfo = "";
  2910.                 String str = "";
  2911.    
  2912.                 text = mContentInfo.mID3Tag.getArtist();
  2913.                 str = new String(text.getTextData(), 0, text.getTextData().length, getTextEncodingType(text.getEncodingType()));
  2914.                 strInfo += str + "\n";
  2915.                
  2916.                 text = mContentInfo.mID3Tag.getTitle();
  2917.                 str = new String(text.getTextData(), 0, text.getTextData().length, getTextEncodingType(text.getEncodingType()));
  2918.                 strInfo += str + "\n";
  2919.                
  2920.                 text = mContentInfo.mID3Tag.getAlbum();
  2921.                 str = new String(text.getTextData(), 0, text.getTextData().length, getTextEncodingType(text.getEncodingType()));
  2922.                 strInfo += str + "\n\n";
  2923.                
  2924.                 text = mContentInfo.mID3Tag.getLyric();
  2925.                 str = new String(text.getTextData(), 0, text.getTextData().length, getTextEncodingType(text.getEncodingType()));
  2926.                 strInfo += str;
  2927.                                
  2928.                 mLyricView.setText(strInfo);
  2929.                
  2930.                 if( text != null ) {
  2931.                     mLyricScrollView.scrollTo(0, 0);
  2932.                     mLyricScrollView.setVisibility(View.VISIBLE);
  2933.                     setLyricScrollViewOutputPosition();
  2934.                 }
  2935.             } else {
  2936.                 mLyricView.setText("");
  2937.             }
  2938.         } catch (Exception e) {
  2939.             Log.d(LOG_TAG, "Exception - setLyric() : " + e.getMessage() );
  2940.             mLyricView.setText("");
  2941.         }
  2942.     }
  2943.    
  2944.     private void setLyricScrollViewOutputPosition() {      
  2945.         Matrix m = mImageView.getImageMatrix();
  2946.         float[] values = new float[9];
  2947.         m.getValues(values);
  2948.        
  2949.         int bmWidth = mImageView.getDrawable().getIntrinsicWidth();
  2950.         int bmHeight = mImageView.getDrawable().getIntrinsicHeight();
  2951.         int transWidth = (int)(values[Matrix.MSCALE_X] * bmWidth);
  2952.         int transHeight = (int)(values[Matrix.MSCALE_Y] * bmHeight);
  2953.        
  2954.         RelativeLayout.LayoutParams params =
  2955.                 new RelativeLayout.LayoutParams(transWidth, transHeight);
  2956.         params.addRule(RelativeLayout.CENTER_IN_PARENT);
  2957.        
  2958.         mLyricScrollView.setLayoutParams(params);
  2959.         mLyricScrollView.requestLayout();
  2960.         mLyricView.setWidth(transWidth);
  2961.     }
  2962.    
  2963.     public String getTextEncodingType(int eType) {
  2964.         if (eType == NexID3TagText.ENCODING_TYPE_UTF16)
  2965.             return new String("UTF-16");
  2966.         else if(eType == NexID3TagText.ENCODING_TYPE_UNICODE)
  2967.             return new String("UTF-16LE");
  2968.         else
  2969.             return new String("UTF-8");
  2970.     }
  2971.    
  2972.     private void updateControllerVisibility() {
  2973.         mHandler.post(new Runnable() {
  2974.            
  2975.             @Override
  2976.             public void run() {
  2977.                 int visibility = (mFileList != null || mNxbWholeList != null) ? View.VISIBLE : View.INVISIBLE;
  2978.                 mPreviousButton.setVisibility(visibility);
  2979.                 mNextButton.setVisibility(visibility);
  2980.  
  2981.                 if( mIsLive ) {
  2982.                     mGoToLiveButton.setVisibility(View.VISIBLE);
  2983.                 }
  2984.             }
  2985.         });
  2986.        
  2987.     }
  2988.  
  2989.     private void enableUIControls(final boolean isEnable){
  2990.         mHandler.post(new Runnable() {
  2991.             @Override
  2992.             public void run() {
  2993.                 if(mPlayPauseButton != null) {
  2994.                     mPlayPauseButton.setEnabled(isEnable);
  2995.                 }
  2996.             }
  2997.         });
  2998.     }
  2999.    
  3000.     private void showBufferStatus(final String message){
  3001.         mHandler.post(new Runnable() {
  3002.             @Override
  3003.             public void run() {
  3004.                 mProgressLayout.setVisibility(View.VISIBLE);
  3005.                 mProgressLayout.requestLayout();
  3006.                 mProgressTextView.setText(message);
  3007.             }
  3008.         });
  3009.     }
  3010.     private void clearBufferStatus(){
  3011.         mHandler.post(new Runnable() {
  3012.             @Override
  3013.             public void run() {
  3014.                 mProgressLayout.setVisibility(View.GONE);
  3015.                 mProgressLayout.requestLayout();
  3016.             }
  3017.         });
  3018.     }
  3019.  
  3020.     @Override
  3021.     public boolean onOptionsItemSelected(MenuItem item) {
  3022.         switch (item.getItemId()) {
  3023.             case R.id.action_multi_stream:
  3024.                 createAndShowMultiStreamDialog();
  3025.                 break;
  3026.             case R.id.action_min_max_bandwidth:
  3027.                 createAndShowBandWidthDialog();
  3028.                 break;
  3029.             case R.id.action_scale:
  3030.                 createAndShowScaleModeDialog();
  3031.                 break;
  3032.             case R.id.action_caption_style:
  3033.                 createAndShowCaptionStyleDialog();
  3034.                 break;
  3035.             case R.id.action_statistics:
  3036.                 createAdnShowStatisticDialog();
  3037.                 break;
  3038.             case R.id.action_volume:
  3039.                 createAndShowVolumeDialog();
  3040.                 break;
  3041.             case R.id.action_dolby_sound:
  3042.                 mDolbyDialog.createAndShow();
  3043.                 break;
  3044.             case R.id.action_target_bandwidth:
  3045.                 mTargetBandWidthDialog.createAndShow(mContentInfo, mNexPlayer.getProperty(NexProperty.SUPPORT_ABR) == 1);
  3046.                 break;
  3047.             case R.id.action_language:
  3048.                 mCaptionLanquageDialog.createAndShowDialog(mContentInfo, mNexPlayer.getCaptionLanguage());
  3049.                 break;
  3050.             case R.id.action_subtitle:
  3051.                 NxbInfo info = NxbInfo.getNxbInfo(mNxbWholeList, mCurrentPath, mCurrentPosition);
  3052.                 mSubtitleChangeDialog.createAndShow(info.getSubtitle(), mCurrentSubtitlePath);
  3053.                 break;
  3054.             case R.id.action_content_info:
  3055.                 createAndShowContentInfoDialog();
  3056.                 break;
  3057.             case R.id.action_pip:
  3058.                 if (supportPIP()) {
  3059.                     //enterPictureInPictureMode();
  3060.                 }
  3061.                 break;
  3062.             default:
  3063.                 return false;
  3064.         }
  3065.  
  3066.         return super.onOptionsItemSelected(item);
  3067.     }
  3068.  
  3069.     private boolean supportPIP() {
  3070.         UiModeManager uiModeManager = (UiModeManager) getSystemService(UI_MODE_SERVICE);
  3071.         Log.d(LOG_TAG, "uiModeManager.getCurrentModeType() uiModeManager.getCurrentModeType() : " + uiModeManager.getCurrentModeType());
  3072.  
  3073.         return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION;
  3074.     }
  3075.  
  3076.     private void createScaleDialog() {
  3077.         mScaleDialog = new AlertDialog.Builder(NexPlayerSample.this)
  3078.                 .setTitle(R.string.scale_mode)
  3079.                 .setItems(R.array.sacle_list_array, new DialogInterface.OnClickListener() {
  3080.  
  3081.                     @Override
  3082.                     public void onClick(DialogInterface dialog, int selectedIndex) {
  3083.                         mScaleMode = selectedIndex;
  3084.                         setPlayerOutputPosition(mScaleMode);
  3085.                     }
  3086.                 }).create();
  3087.     }
  3088.  
  3089.     private void createAndShowScaleModeDialog() {
  3090.         if( mScaleDialog == null ) {
  3091.             createScaleDialog();
  3092.         }
  3093.  
  3094.         if( !mScaleDialog.isShowing() )
  3095.             mScaleDialog.show();
  3096.     }
  3097.  
  3098.     @Override
  3099.     public boolean onCreateOptionsMenu(Menu menu) {
  3100.         MenuInflater inflater = getMenuInflater();
  3101.         inflater.inflate(R.menu.player_activity_action, menu);
  3102.         return super.onCreateOptionsMenu(menu);
  3103.     }
  3104.  
  3105.     @Override
  3106.     public boolean onMenuOpened(int featureId, Menu menu) {
  3107.         if (menu != null && menu.findItem(R.id.bandwidth) != null) {
  3108.             NxbInfo info = NxbInfo.getNxbInfo(mNxbWholeList, mCurrentPath, mCurrentPosition);
  3109.             List<String> subtitleList = info.getSubtitle();
  3110.  
  3111.             menu.findItem(R.id.action_statistics).setVisible(mPrefData.mEnableStatisticsMonitor);
  3112.             menu.findItem(R.id.action_multi_stream).setEnabled(!mFastPlay);
  3113.             menu.findItem(R.id.action_pip).setVisible(supportPIP());
  3114.             menu.findItem(R.id.bandwidth).getSubMenu().findItem(R.id.action_min_max_bandwidth).setEnabled(!mFastPlay);
  3115.  
  3116.             boolean dolbyVisible = false;
  3117.             boolean captionLanguageVisible = false;
  3118.             boolean volumeVisible = false;
  3119.  
  3120.             if( mContentInfo != null ) {
  3121.                 dolbyVisible = (mIsEnginOpen && mContentInfo.mAudioCodec == NexContentInformation.NEXOTI_EC3) ||
  3122.                         (mIsEnginOpen && mContentInfo.mAudioCodec == NexContentInformation.NEXOTI_AC3);
  3123.                 captionLanguageVisible = mContentInfo.mCaptionLanguages != null && mContentInfo.mCaptionLanguages.length > 0;
  3124.                 volumeVisible = mContentInfo.mCurrAudioStreamID != NexPlayer.MEDIA_STREAM_DISABLE_ID;
  3125.             }
  3126.             menu.findItem(R.id.audio).getSubMenu().findItem(R.id.action_dolby_sound).setVisible(dolbyVisible);
  3127.             menu.findItem(R.id.audio).getSubMenu().findItem(R.id.action_volume).setVisible(volumeVisible);
  3128.             menu.findItem(R.id.text).getSubMenu().findItem(R.id.action_language).setVisible(captionLanguageVisible);
  3129.             menu.findItem(R.id.text).getSubMenu().findItem(R.id.action_subtitle).setVisible(subtitleList.size() > 0);
  3130.         }
  3131.  
  3132.         return super.onMenuOpened(featureId, menu);
  3133.     }
  3134.    
  3135.     @SuppressLint("NewApi")
  3136.     void setPlayerOutputPosition(int scaleMode) {
  3137.         int width, height, top, left;
  3138.         width = height = top = left = 0;
  3139.         final int screenWidth = mVideoView.getWidth();
  3140.         final int screenHeight = mVideoView.getHeight();
  3141.         Log.d(LOG_TAG, "setPlayerOutputPosition screenWidth : " + screenWidth + " screenHeight : " + screenHeight);
  3142.         if (mVideoWidth == 0 && mVideoHeight == 0) //(mVideoWidth == 0 && mVideoHeight == 0) means Video Off state
  3143.             scaleMode = SCALE_STRETCH_TO_SCREEN;
  3144.  
  3145.         float scale = 1f;
  3146.  
  3147.         switch (scaleMode) {
  3148.             case SCALE_FIT_TO_SCREEN:
  3149.                 scale = Math.min((float) screenWidth / (float) mVideoWidth,
  3150.                         (float) screenHeight / (float) mVideoHeight);
  3151.  
  3152.                 width = (int) (mVideoWidth * scale);
  3153.                 height = (int) (mVideoHeight * scale);
  3154.                 top = (screenHeight - height) / 2;
  3155.                 left = (screenWidth - width) / 2;
  3156.  
  3157.                 break;
  3158.             case SCALE_ORIGINAL:
  3159.                 width = mVideoWidth;
  3160.                 height = mVideoHeight;
  3161.                 top = (screenHeight - mVideoHeight) / 2;
  3162.                 left = (screenWidth - mVideoWidth) / 2;
  3163.  
  3164.                 break;
  3165.             case SCALE_STRETCH_TO_SCREEN:
  3166.                 width = screenWidth;
  3167.                 height = screenHeight;
  3168.  
  3169.  
  3170.                 if(mVideoWidth != 0 && mVideoHeight != 0) {
  3171.                     scale = Math.min((float) screenWidth / (float) mVideoWidth,
  3172.                             (float) screenHeight / (float) mVideoHeight);
  3173.                 }
  3174.  
  3175.                 break;
  3176.         }
  3177.  
  3178.         mCaptionPainter.setRenderingArea(new Rect(left, top, left + width, top + height), scale);
  3179.         mHandler.post(new Runnable() {
  3180.             @Override
  3181.             public void run() {
  3182.                 mCaptionPainter.invalidate();
  3183.             }
  3184.         });
  3185.  
  3186.         if (mContentInfo != null && mContentInfo.mCurrVideoStreamID != NexPlayer.MEDIA_STREAM_DISABLE_ID) {
  3187.             mVideoView.setOutputPos(left, top, width, height);
  3188.         }
  3189.     }
  3190.  
  3191.     public void prepareCaptionDialog(AlertDialog dialog) {
  3192.         captionStyleDialogUtil.setListener(new CaptionStyleDialogUtil.IListener() {
  3193.             @Override
  3194.             public void didClickButton(CaptionStyleDialogUtil.BUTTON button, AlertDialog dialog) {
  3195.                 switch(button) {
  3196.                     case SAVE:
  3197.                         //captionRenderer.setUserCaptionSettings(captionStyleDialogUtil.getCaptionSettings());
  3198.                         dialog.dismiss();
  3199.                     break;
  3200.  
  3201.                     case RESET:
  3202.                     break;
  3203.  
  3204.                     case CANCEL:
  3205.                         //captionStyleDialogUtil.restoreCaptionPreview(captionRenderer.getCaptionSettings());
  3206.                         dialog.dismiss();
  3207.                     break;
  3208.                 }
  3209.             }
  3210.  
  3211.             @Override
  3212.             public void didChangeCaptionFontColor(CaptionColor fontColor) {
  3213.             }
  3214.  
  3215.             @Override
  3216.             public void didChangeFontOpacity(int fontOpacity) {
  3217.             }
  3218.  
  3219.             @Override
  3220.             public void canceledDialog() {
  3221.                 //BackButton Event Callback.
  3222.                 //captionStyleDialogUtil.restoreCaptionPreview(captionRenderer.getCaptionSettings());
  3223.             }
  3224.  
  3225.         });
  3226.  
  3227.         //captionStyleDialogUtil.setUserCaptionSettings(captionRenderer.getCaptionSettings());
  3228.         captionStyleDialogUtil.prepareCaptionDialog(this, dialog);
  3229.     }
  3230.  
  3231.     private void changeDolbyPostProcessingValue(int position){
  3232.         mNexPlayer.setProperties(DolbyDialog.AC3_PROPERTY_POST_PROCESSING, position);
  3233.     }
  3234.  
  3235.     private void changeDolbyEndPointValue(int position){
  3236.         Log.d(LOG_TAG, "AC3. SetEndPoint : " + (position+1));
  3237.         mNexPlayer.setProperties(DolbyDialog.AC3_PROPERTY_END_POINT, position+1);
  3238.     }
  3239.  
  3240.     private void changeDolbyEnhancementGainValue(int position){
  3241.         Log.d(LOG_TAG, "AC3. Set Enhancement Gain : " + position+1);
  3242.         mNexPlayer.setProperties(DolbyDialog.AC3_PROPERTY_ENHANCEMENT_GAIN, position);
  3243.     }
  3244.  
  3245.     private void clearCaptionString() {
  3246.         mHandler.post(new Runnable() {
  3247.             @Override
  3248.             public void run() {
  3249.                 mTimedMetaTextView.setText("");
  3250.                 mCaptionPainter.clear();
  3251.             }
  3252.         });
  3253.     }
  3254.  
  3255.     private void createAdnShowStatisticDialog() {
  3256.         mStatisticsDialog.show();
  3257.     }
  3258.  
  3259.     private void createAndShowBandWidthDialog() {
  3260.         mBandwidthDialog.createAndShow(mPrefData.mMinBandWidth, mPrefData.mMaxBandWidth, new IBandwidthListener() {
  3261.  
  3262.             @Override
  3263.             public void onBandwidthDialogUpdated(int minBW, int maxBW) {
  3264.                 boolean isChangedMaxBW = mPrefData.mMaxBandWidth != maxBW;
  3265.                 boolean isChangedMinBW = mPrefData.mMinBandWidth != minBW;
  3266.                 NexErrorCode ret = NexErrorCode.UNKNOWN;
  3267.                 if( isChangedMaxBW && isChangedMinBW ) {
  3268.                     ret = mABRController.changeMinMaxBandWidth(minBW*BANDWIDTH_KBPS, maxBW*BANDWIDTH_KBPS);
  3269.                 } else if( isChangedMaxBW ) {
  3270.                     ret = mABRController.changeMaxBandWidth(maxBW*BANDWIDTH_KBPS);
  3271.                 } else if( isChangedMinBW ) {
  3272.                     ret = mABRController.changeMinBandWidth(minBW*BANDWIDTH_KBPS);
  3273.                 }
  3274.                 Log.d(LOG_TAG, "changeMinMaxBandWidth Ret : " + ret);
  3275.             }
  3276.         });
  3277.     }
  3278.    
  3279.     private void createAndShowCaptionStyleDialog() {
  3280.         if (mCaptionDialog == null) {
  3281.             mCaptionDialog = new CaptionStyleDialog(this, new CaptionStyleDialog.OnSettingsChangedListener() {
  3282.                 @Override
  3283.                 public void onSettingsChanged(NexCaptionSetting settings) {
  3284.                     mCaptionPainter.setUserCaptionSettings(settings);
  3285.  
  3286.                     mHandler.post(new Runnable() {
  3287.                         @Override
  3288.                         public void run() {
  3289.                             mCaptionPainter.invalidate();
  3290.                         }
  3291.                     });
  3292.                 }
  3293.             });
  3294.         }
  3295.  
  3296.         if (!mCaptionDialog.isShowing()) {
  3297.             mCaptionDialog.createAndShow(mCaptionPainter.getUserCaptionSettings());
  3298.         }
  3299.     }
  3300.  
  3301.     private void createAndShowVolumeDialog() {
  3302.         mVolumeDialog.createAndShow(mVolume, new IVolumeListener() {
  3303.             @Override
  3304.             public void onVolumeDialogUpdated(VOLUME_BUTTON button, int volume) {
  3305.                 if( button == VOLUME_BUTTON.PROGRESS_CHANGED) {
  3306.                     mVolume = volume;
  3307.                     setVolume();
  3308.                 }
  3309.             }
  3310.         });
  3311.     }
  3312.  
  3313.     private void createAndShowMultiStreamDialog() {
  3314.         boolean is608Caption = false;
  3315.         boolean is708Caption = false;
  3316.  
  3317.         if (null != mContentInfo && AUDIO_ONLY != mContentInfo.mMediaType) {
  3318.             int captionType = mCaptionPainter.getCaptionType();
  3319.             is608Caption = captionType == NexContentInformation.NEX_TEXT_CEA608;
  3320.             is708Caption = captionType == NexContentInformation.NEX_TEXT_CEA708;
  3321.         }
  3322.  
  3323.         mMultistreamDialog.createAndShow(mContentInfo, is608Caption, is708Caption, mCEA608CaptionChannel, new IMultiStreamListener() {
  3324.  
  3325.             @Override
  3326.             public void onVideoStreamDialogUpdated(MULTISTREAM_BUTTON button, int streamID, int attrID) {
  3327.                 if (button == MultiStreamDialog.MULTISTREAM_BUTTON.OK) {
  3328.                     if (mContentInfo.mCurrVideoStreamID != streamID ||
  3329.                             NexContentInfoExtractor.getCurCustomAttributeID(mContentInfo, NexPlayer.MEDIA_STREAM_TYPE_VIDEO) != attrID ) {
  3330.                         if( mPrefData.mEnableDynamicThumbnail ) {
  3331.                             if( streamID != NexPlayer.MEDIA_STREAM_DISABLE_ID ) {
  3332.                                 if( mTempVideoStreamID == streamID && mContentInfo.mCurrVideoStreamID == NexPlayer.MEDIA_STREAM_DISABLE_ID ) {
  3333.                                     mSeekBar.enableDynamicThumbnail(true);
  3334.                                 } else {
  3335.                                     disableDynamicThumbnail();
  3336.                                     enableDynamicThumbnail();
  3337.                                     setDynamicThumbnailOption(mContentInfo);
  3338.                                 }
  3339.                             } else {
  3340.                                 mTempVideoStreamID = mContentInfo.mCurrVideoStreamID;
  3341.                                 mSeekBar.enableDynamicThumbnail(false);
  3342.                             }
  3343.                         }
  3344.  
  3345.                         changeVideoStream(streamID, attrID);
  3346.                         mMultistreamDialog.dismiss();
  3347.                     }
  3348.                 }
  3349.             }
  3350.  
  3351.             @Override
  3352.             public void onTextStreamDialogUpdated(MULTISTREAM_BUTTON button, int streamID) {
  3353.                 if (button == MultiStreamDialog.MULTISTREAM_BUTTON.OK) {
  3354.                     boolean shouldSetMediaStream = false;
  3355.                     boolean is608Caption = false;
  3356.  
  3357.                     if (null != mContentInfo && AUDIO_ONLY != mContentInfo.mMediaType) {
  3358.                         is608Caption = mCaptionPainter.getCaptionType() == NexContentInformation.NEX_TEXT_CEA608;
  3359.                     }
  3360.  
  3361.                     if (is608Caption) {
  3362.                         if (mCEA608CaptionChannel != streamID) {
  3363.                             shouldSetMediaStream = true;
  3364.                             mCEA608CaptionChannel = streamID;
  3365.                         }
  3366.                     } else if (mContentInfo.mCurrTextStreamID != streamID) {
  3367.                         shouldSetMediaStream = true;
  3368.                     }
  3369.  
  3370.                     if (shouldSetMediaStream) {
  3371.                         changeTextStream(is608Caption, streamID);
  3372.                         mMultistreamDialog.dismiss();
  3373.                     }
  3374.                 }
  3375.             }
  3376.  
  3377.             @Override
  3378.             public void onAudioStreamDialogUpdated(MULTISTREAM_BUTTON button, int streamID) {
  3379.                 if (button == MultiStreamDialog.MULTISTREAM_BUTTON.OK) {
  3380.                     if (mContentInfo.mCurrAudioStreamID != streamID) {
  3381.                         changeAudioStream(streamID);
  3382.                         mMultistreamDialog.dismiss();
  3383.                     }
  3384.                 }
  3385.             }
  3386.         });
  3387.     }
  3388.  
  3389.     private void changeAudioStream(int streamId) {
  3390.         mNexPlayer.setMediaStream(
  3391.                 streamId,
  3392.                 mContentInfo.mCurrTextStreamID == NexPlayer.MEDIA_STREAM_DISABLE_ID ? NexPlayer.MEDIA_STREAM_DISABLE_ID : NexPlayer.MEDIA_STREAM_DEFAULT_ID,
  3393.                 mContentInfo.mCurrVideoStreamID == NexPlayer.MEDIA_STREAM_DISABLE_ID ? NexPlayer.MEDIA_STREAM_DISABLE_ID : NexPlayer.MEDIA_STREAM_DEFAULT_ID,
  3394.                 NexPlayer.MEDIA_STREAM_DEFAULT_ID);
  3395.     }
  3396.  
  3397.     private void changeTextStream(boolean cea608, int streamId) {
  3398.         if( cea608 ) {
  3399.             mNexPlayer.setCEA608CaptionChannel(streamId);
  3400.             clearCaptionString();
  3401.         } else {
  3402.             mNexPlayer.setMediaStream(
  3403.                     mContentInfo.mCurrAudioStreamID == NexPlayer.MEDIA_STREAM_DISABLE_ID ? NexPlayer.MEDIA_STREAM_DISABLE_ID : NexPlayer.MEDIA_STREAM_DEFAULT_ID,
  3404.                     streamId,
  3405.                     mContentInfo.mCurrVideoStreamID == NexPlayer.MEDIA_STREAM_DISABLE_ID ? NexPlayer.MEDIA_STREAM_DISABLE_ID : NexPlayer.MEDIA_STREAM_DEFAULT_ID,
  3406.                     NexPlayer.MEDIA_STREAM_DEFAULT_ID);
  3407.         }
  3408.     }
  3409.  
  3410.     private void changeVideoStream(int streamId, int customAttrId) {
  3411.         mNexPlayer.setMediaStream(
  3412.                 mContentInfo.mCurrAudioStreamID == NexPlayer.MEDIA_STREAM_DISABLE_ID ? NexPlayer.MEDIA_STREAM_DISABLE_ID : NexPlayer.MEDIA_STREAM_DEFAULT_ID,
  3413.                 mContentInfo.mCurrTextStreamID == NexPlayer.MEDIA_STREAM_DISABLE_ID ? NexPlayer.MEDIA_STREAM_DISABLE_ID : NexPlayer.MEDIA_STREAM_DEFAULT_ID,
  3414.                 streamId,
  3415.                 customAttrId);
  3416.     }
  3417.    
  3418.     private Runnable updateStatisticsThread = new Runnable() {
  3419.         public void run() {
  3420.             mHandler.postDelayed(this, 1000);
  3421.         }
  3422.     };
  3423.  
  3424.     private void postProcessingForStopCmd() {
  3425.         Log.d(LOG_TAG, "postProcessingForStopCmd mCurrentPath : " + mCurrentPath + " mForeground : " + mForeground);
  3426.  
  3427.         // stopped by onError
  3428.         if (mPlayerState == PLAYER_FLOW_STATE.BEGINNING_OF_ONERROR)
  3429.         {
  3430.             mHandler.post(new Runnable() {
  3431.                 @Override
  3432.                 public void run() {
  3433.                     closePlayer();
  3434.                     mPlayerState = PLAYER_FLOW_STATE.END_OF_ONERROR;
  3435.                 }
  3436.             });
  3437.         }
  3438.         else
  3439.         {
  3440.             if ( null == mCurrentPath ) {
  3441.                 /*
  3442.                  * Playback has been completed, no next content to play. Finishing the activity.
  3443.                  * onDestroy() will take care of close()/release() of mNexPlayer and mNexALFactory
  3444.                  */
  3445.                 Log.d(LOG_TAG, "null == mCurrentPath");
  3446.                 mPlayerState = PLAYER_FLOW_STATE.FINISH_ACTIVITY;
  3447.                 finish();
  3448.             } else if(mExistFollowingContentPath) {
  3449.                 // stopped by previous/next button
  3450.                 if (mForeground) {
  3451.                     System.gc();
  3452.                     mHaveToStartPlayer = false;
  3453.                     mHandler.postDelayed(new Runnable() {
  3454.                         @Override
  3455.                         public void run() {
  3456.                             startPlay();
  3457.                         }
  3458.                     }, 300);
  3459.                 }
  3460.             }
  3461.         }
  3462.     }
  3463.  
  3464.     protected boolean isStreaming() {
  3465.         return mIsStreaming;
  3466.     }
  3467.  
  3468.     @Override
  3469.     public void onNetworkStateChanged(Context context) {
  3470.         if( NetworkUtils.getConnectivityStatus(context) != NetworkUtils.TYPE_NOT_CONNECTED ) {
  3471.             if( mNexPlayer != null && mNexPlayer.isInitialized() && isStreaming() ) {
  3472.                 int state = mNexPlayer.getState();
  3473.  
  3474.                 if( state == NexPlayer.NEXPLAYER_STATE_PLAY || state == NexPlayer.NEXPLAYER_STATE_PAUSE )
  3475.                     mNexPlayer.reconnectNetwork();
  3476.             }
  3477.         }
  3478.     }
  3479.  
  3480.     //Google IMA
  3481.     /**
  3482.      * Request video ads from the given VAST ad tag.
  3483.      * @param adTagUrl URL of the ad's VAST XML
  3484.      */
  3485.     private void requestAds(String adTagUrl){
  3486.         AdDisplayContainer adDisplayContainer = mSdkFactory.createAdDisplayContainer();
  3487.         adDisplayContainer.setAdContainer(mAdUiContainer);
  3488.  
  3489.         // Create the ads request.
  3490.         AdsRequest request = mSdkFactory.createAdsRequest();
  3491.         request.setAdTagUrl(adTagUrl);
  3492.         request.setAdDisplayContainer(adDisplayContainer);
  3493.         request.setContentProgressProvider(new ContentProgressProvider() {
  3494.             @Override
  3495.             public VideoProgressUpdate getContentProgress() {
  3496.                 if (mIsAdDisplayed || mNexPlayer == null || mNexPlayer.getContentInfo().mMediaDuration <= 0) {
  3497.                     return VideoProgressUpdate.VIDEO_TIME_NOT_READY;
  3498.                 }
  3499.                 return new VideoProgressUpdate(mNexPlayer.getCurrentPosition(),
  3500.                         mNexPlayer.getContentInfo().mMediaDuration);
  3501.             }
  3502.         });
  3503.  
  3504.         // Request the ad. After the ad is loaded, onAdsManagerLoaded() will be called.
  3505.         mAdsLoader.requestAds(request);
  3506.     }
  3507. }
Add Comment
Please, Sign In to add comment