org.videolan.vlc.gui.video.VideoPlayerActivity.java Source code

Java tutorial

Introduction

Here is the source code for org.videolan.vlc.gui.video.VideoPlayerActivity.java

Source

/*****************************************************************************
 * VideoPlayerActivity.java
 *****************************************************************************
 * Copyright ? 2011-2013 VLC authors and VideoLAN
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

package org.videolan.vlc.gui.video;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.StreamCorruptedException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.json.JSONException;
import org.json.JSONObject;
import org.videolan.libvlc.EventHandler;
import org.videolan.libvlc.IVideoPlayer;
import org.videolan.libvlc.LibVLC;
import org.videolan.libvlc.LibVlcException;
import org.videolan.vlc.AudioServiceController;
import org.videolan.vlc.Media;
import org.videolan.vlc.MediaDatabase;
import org.videolan.vlc.Util;
import org.videolan.vlc.VLCApplication;
import org.videolan.vlc.WeakHandler;
import org.videolan.vlc.gui.PreferencesActivity;
import org.videolan.vlc.interfaces.IPlayerControl;
import org.videolan.vlc.interfaces.OnPlayerControlListener;
import org.videolan.vlc.widget.PlayerControlClassic;
import org.videolan.vlc.widget.PlayerControlWheel;

import com.example.pingtaitest.ActivityControlDevice;
import com.example.pingtaitest.ActivityDevice;
import com.example.pingtaitest.ActivityShiPin;
import com.example.pingtaitest.MainActivity;
import com.example.pingtaitest.WebServiceUtil;
import com.example.pingtaitest.utils.GetURLControl;
import com.example.pingtaitest.utils.MD5Util;
import com.example.pingtaitest.utils.SyncHttpRequestService;
import com.example.pingtaitest.utils.TimeUtil;
import com.hikvision.wifi.configuration.DeviceDiscoveryListener;

import android.R.integer;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.KeyguardManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.database.Cursor;
import android.graphics.Color;
import android.graphics.ImageFormat;
import android.graphics.PixelFormat;
import android.graphics.drawable.AnimationDrawable;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.net.wifi.WifiInfo;
import android.opengl.Visibility;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.provider.MediaStore.MediaColumns;
import android.provider.Settings.SettingNotFoundException;
import android.text.format.DateFormat;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.OrientationEventListener;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnSystemUiVisibilityChangeListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.view.animation.AnimationUtils;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.SeekBar;
import android.widget.Toast;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import cn.ffcs.vlcdemo.Constant;
import cn.ffcs.vlcdemo.R;
import cn.ffcs.vlcdemo.ShowNotifyDialog;

public class VideoPlayerActivity extends Activity implements IVideoPlayer {
    public final static String TAG = "VLC/VideoPlayerActivity";

    // Internal intent identifier to distinguish between internal launch and
    // external intent.
    private final static String PLAY_FROM_VIDEOGRID = "org.videolan.vlc.gui.video.PLAY_FROM_VIDEOGRID";

    private SurfaceView mSurface;
    private SurfaceHolder mSurfaceHolder;
    private FrameLayout mSurfaceFrame;
    private int mSurfaceAlign;
    private LibVLC mLibVLC;
    private String mLocation;
    private static int cameraId = -1;
    private static final int SURFACE_BEST_FIT = 0;
    private static final int SURFACE_FIT_HORIZONTAL = 1;
    private static final int SURFACE_FIT_VERTICAL = 2;
    private static final int SURFACE_FILL = 3;
    private static final int SURFACE_16_9 = 4;
    private static final int SURFACE_4_3 = 5;
    private static final int SURFACE_ORIGINAL = 6;
    private int mCurrentSize = SURFACE_4_3;
    /** Overlay */

    private View mOverlayHeader;
    private View mOverlayLock;
    private View mOverlayOption;
    private View mOverlayProgress;
    private View mOverlayInterface;
    private static final int OVERLAY_TIMEOUT = 4000;
    private static final int OVERLAY_INFINITE = 3600000;
    private static final int FADE_OUT = 1;
    private static final int SHOW_PROGRESS = 2;
    private static final int SURFACE_SIZE = 3;
    private static final int FADE_OUT_INFO = 4;
    private boolean mDragging;
    private boolean mShowing;
    private int mUiVisibility = -1;
    private SeekBar mSeekbar;
    private TextView mTitle;
    private TextView mSysTime;
    private TextView mBattery;
    private TextView mTime;
    private TextView mLength;
    private TextView mInfo, mRadio_tv;
    private IPlayerControl mControls;
    private boolean mEnableWheelbar;
    private boolean mEnableBrightnessGesture;
    private boolean mDisplayRemainingTime = false;
    private int mScreenOrientation;
    private ImageButton mAudioTrack;
    private ImageButton mSubtitle;
    private ImageButton mLock;
    private ImageButton mSize;
    private ImageButton mSnapShot;
    private ImageButton mRecord;
    private ImageButton mRadio;
    private ImageButton mVoice;
    private boolean mRecording = false;
    private boolean mIsLocked = false;
    private int mRetry = 0;
    private int mRetryMax = 3;
    private int mLastAudioTrack = -1;
    private int mLastSpuTrack = -2;

    private RelativeLayout play_lay;
    private LinearLayout progress_lay;

    private LinearLayout snapshot_lay, radio_onOrPause_lay, record_lay, voice_lay;

    /**
     * For uninterrupted switching between audio and video mode
     */
    private boolean mSwitchingView;
    private boolean mEndReached;

    // Playlist
    private int savedIndexPosition = -1;

    // size of the video
    private int mVideoHeight;
    private int mVideoWidth;
    private int mSarNum;
    private int mSarDen;
    private int mVideoVisibleHeight;
    private int mVideoVisibleWidth;
    //Volume
    private AudioManager mAudioManager;
    private int mAudioMax;
    //Volume Or Brightness
    private boolean mIsAudioOrBrightnessChanged;
    private int mSurfaceYDisplayRange;
    private float mTouchY, mTouchX, mVol;

    // Brightness
    private boolean mIsFirstBrightnessGesture = true;
    private LinearLayout msgContainer;
    // Tracks & Subtitles
    private Map<Integer, String> mAudioTracksList;
    private Map<Integer, String> mSubtitleTracksList;
    /**
     * Used to store a selected subtitle; see onActivityResult.
     * It is possible to have multiple custom subs in one session
     * (just like desktop VLC allows you as well.)
     */
    private ArrayList<String> mSubtitleSelectedFiles = new ArrayList<String>();

    private int sdk = android.os.Build.VERSION.SDK_INT;

    private long clickTime = 0;
    private LinearLayout directionLayout;

    private OrientationEventListener mOrientationListener;
    private boolean mScreenProtrait = true;
    private boolean mCurrentOrient = false;
    private ImageButton left, right, top, bottom;
    private ArrayList<Integer> devList;
    HashMap<Integer, Integer> dev_typeMap;
    private final OnClickListener directionListenr = new OnClickListener() {
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
            case R.id.top:
                controlDevice(1);
                break;
            case R.id.bottom:
                controlDevice(2);
                break;
            case R.id.left:
                controlDevice(3);
                break;
            case R.id.right:
                controlDevice(4);
                break;

            }
        }
    };

    public void controlDevice(final int pdz) {
        if (cameraId == -1) {
            Toast.makeText(VideoPlayerActivity.this, "???", Toast.LENGTH_SHORT)
                    .show();
        } else {
            new Thread() {
                @Override
                public void run() {
                    // ???

                    int deviceID = cameraId * 100 + pdz;

                    String responseCode = GetURLControl.httpGet(deviceID);
                    Message message = new Message();
                    try {
                        JSONObject jsonObject = new JSONObject(responseCode);
                        if (jsonObject.getInt("result") == 0) {
                            message.what = 0;
                        } else {
                            message.what = 1;
                        }
                        handler.sendMessage(message);
                    } catch (JSONException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        message.what = 0;
                    }
                    Log.e("---", responseCode);
                }
            }.start();
        }
    }

    Handler handler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            // TODO Auto-generated method stub
            super.handleMessage(msg);
            switch (msg.what) {
            case 0:
                Toast.makeText(VideoPlayerActivity.this, "??", Toast.LENGTH_SHORT).show();

                break;

            case 1:
                Toast.makeText(VideoPlayerActivity.this, "?", Toast.LENGTH_SHORT).show();
                break;
            }
        }

    };

    private class MyHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.obj != null) {
                List<String> msgList = (List<String>) msg.obj;
                for (int i = 0; i < msgList.size(); i++) {
                    TextView msgText = (TextView) msgContainer.getChildAt(i).findViewById(R.id.msg);
                    msgText.setText(MainActivity.generateResult(dev_typeMap.get(devList.get(i)), msgList.get(i)));
                }
            }

        }
    }

    @Override
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.player);
        final MyHandler myHandler = new MyHandler();
        final LayoutInflater inflater = LayoutInflater.from(this);
        msgContainer = (LinearLayout) findViewById(R.id.msg_container);
        int current_locID;
        if (ActivityDevice.current_locID == -1)
            current_locID = ActivityShiPin.current_locID;
        else
            current_locID = ActivityDevice.current_locID;
        ArrayList<Integer> locIDList = MainActivity.locIDList;
        HashMap<Integer, ArrayList<Integer>> loc_devMap = MainActivity.loc_devMap;
        dev_typeMap = MainActivity.dev_typeMap;
        HashMap<Integer, String> dev_nameMap = MainActivity.dev_nameMap;
        Log.e("*****localID", String.valueOf(current_locID));
        if (current_locID != -1) {
            if (loc_devMap.containsKey(current_locID)) {
                devList = loc_devMap.get(current_locID);
                if (devList.size() != 0) {
                    int sub = devList.get(0) - 0;
                    final ArrayList<Integer> brokenList = new ArrayList<Integer>();
                    brokenList.add(0);
                    int i;
                    for (i = 0; i < devList.size(); i++) {
                        int devID = devList.get(i);
                        Log.e("@@@@@@@@", String.valueOf(i));
                        if (sub != devID - i) {
                            brokenList.add(i);
                            sub = devID - i;
                        }
                        //int typeID=dev_typeMap.get(devID);
                        final View view = inflater.inflate(R.layout.senssor_msg, null);
                        TextView type = (TextView) view.findViewById(R.id.type);
                        TextView msg = (TextView) view.findViewById(R.id.msg);
                        type.setText(dev_nameMap.get(devID) + ":");
                        msgContainer.addView(view);

                    }
                    brokenList.add(i);
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            Log.e(">>>>>>>>>", "??");
                            String a = null;
                            try {
                                a = WebServiceUtil.getHd("sss", "njuptcloud");
                            } catch (Exception e1) {
                                // TODO Auto-generated catch block
                                //Toast.makeText(VideoPlayerActivity.this,"?a " , Toast.LENGTH_SHORT).show();
                                Log.e(">>>>>>>>>", "?a " + e1.getMessage());
                                e1.printStackTrace();

                            }
                            if (a != null) {
                                int i = 0;
                                List<String> msgList = new ArrayList<String>();
                                while (i < (brokenList.size() - 1)) {
                                    try {
                                        //Toast.makeText(VideoPlayerActivity.this,"??... " , Toast.LENGTH_SHORT).show();
                                        msgList.addAll(WebServiceUtil.getMs(a, devList.get(brokenList.get(i)),
                                                devList.get(brokenList.get(i + 1) - 1)));
                                    } catch (Exception e) {
                                        //Toast.makeText(VideoPlayerActivity.this,"?? " , Toast.LENGTH_SHORT).show();
                                        e.printStackTrace();
                                    }
                                    i++;
                                }
                                //                              List<String> resultList=new ArrayList<String>();
                                //                              resultList.add(object)
                                Message msg = new Message();
                                //Toast.makeText(VideoPlayerActivity.this,msgList.get(0) , Toast.LENGTH_SHORT).show();
                                msg.obj = msgList;
                                myHandler.sendMessage(msg);
                            } else {
                                Log.e(">>>>>>>", "??");
                                Message msg = new Message();
                                //Toast.makeText(VideoPlayerActivity.this,msgList.get(0) , Toast.LENGTH_SHORT).show();
                                msg.obj = null;
                                myHandler.sendMessage(msg);
                            }

                            //Toast.makeText(VideoPlayerActivity.this, "??", Toast.LENGTH_SHORT).show();
                        }
                    }).start();
                }
            }
        }

        directionLayout = (LinearLayout) findViewById(R.id.direction_layout);

        left = (ImageButton) findViewById(R.id.left);
        left.setOnClickListener(directionListenr);
        bottom = (ImageButton) findViewById(R.id.bottom);
        bottom.setOnClickListener(directionListenr);
        top = (ImageButton) findViewById(R.id.top);
        top.setOnClickListener(directionListenr);
        right = (ImageButton) findViewById(R.id.right);
        right.setOnClickListener(directionListenr);

        SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
        if (Util.isICSOrLater())
            getWindow().getDecorView().findViewById(android.R.id.content)
                    .setOnSystemUiVisibilityChangeListener(new OnSystemUiVisibilityChangeListener() {
                        @Override
                        public void onSystemUiVisibilityChange(int visibility) {
                            if (visibility == mUiVisibility)
                                return;
                            setSurfaceSize(mVideoWidth, mVideoHeight, mVideoVisibleWidth, mVideoVisibleHeight,
                                    mSarNum, mSarDen);
                            if (visibility == View.SYSTEM_UI_FLAG_VISIBLE && !mShowing) {
                                showOverlay();
                            }
                            mUiVisibility = visibility;
                        }
                    });

        /** initialize Views an their Events */
        mOverlayHeader = findViewById(R.id.player_overlay_header);
        mOverlayHeader.setVisibility(View.GONE);
        mOverlayLock = findViewById(R.id.lock_overlay);
        mOverlayOption = findViewById(R.id.option_overlay);
        mOverlayProgress = findViewById(R.id.progress_overlay);
        mOverlayInterface = findViewById(R.id.interface_overlay);

        play_lay = (RelativeLayout) findViewById(R.id.play_lay);
        progress_lay = (LinearLayout) findViewById(R.id.progress_lay);

        /* header */
        mTitle = (TextView) findViewById(R.id.player_overlay_title);
        mSysTime = (TextView) findViewById(R.id.player_overlay_systime);
        mBattery = (TextView) findViewById(R.id.player_overlay_battery);

        // Position and remaining time
        mTime = (TextView) findViewById(R.id.player_overlay_time);
        mTime.setOnClickListener(mRemainingTimeListener);
        mLength = (TextView) findViewById(R.id.player_overlay_length);
        mLength.setOnClickListener(mRemainingTimeListener);

        // the info textView is not on the overlay
        mInfo = (TextView) findViewById(R.id.player_overlay_info);

        mEnableWheelbar = pref.getBoolean("enable_wheel_bar", false);
        mEnableBrightnessGesture = pref.getBoolean("enable_brightness_gesture", true);
        mScreenOrientation = Integer
                .valueOf(pref.getString("screen_orientation_value", "4" /*SCREEN_ORIENTATION_SENSOR*/));

        mControls = mEnableWheelbar ? new PlayerControlWheel(this) : new PlayerControlClassic(this);
        mControls.setOnPlayerControlListener(mPlayerControlListener);
        FrameLayout mControlContainer = (FrameLayout) findViewById(R.id.player_control);
        mControlContainer.addView((View) mControls);

        mAudioTrack = (ImageButton) findViewById(R.id.player_overlay_audio);
        mAudioTrack.setVisibility(View.GONE);
        mSubtitle = (ImageButton) findViewById(R.id.player_overlay_subtitle);
        mSubtitle.setVisibility(View.GONE);

        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                /*FIXME
                 * The setTracksAndSubtitles method probably doesn't work in case of many many Tracks and Subtitles
                 * Moreover, in a video stream, if Tracks & Subtitles change, they won't be updated
                 */
                setESTrackLists();
            }
        }, 1500);

        mLock = (ImageButton) findViewById(R.id.lock_overlay_button);
        mLock.setOnClickListener(mLockListener);

        mSize = (ImageButton) findViewById(R.id.player_overlay_size);
        mSize.setOnClickListener(mSizeListener);

        snapshot_lay = (LinearLayout) findViewById(R.id.snapshot_lay);//??
        radio_onOrPause_lay = (LinearLayout) findViewById(R.id.radio_onOrPause_lay);//???        record_lay = (LinearLayout) findViewById(R.id.record_lay);//
        voice_lay = (LinearLayout) findViewById(R.id.voice_lay);//

        mSnapShot = (ImageButton) findViewById(R.id.snapshot_overlay_button);
        mSnapShot.setOnClickListener(mSnapShotListener);

        mRecord = (ImageButton) findViewById(R.id.record_overlay_button);
        mRecord.setOnClickListener(mRecordListener);

        //???        
        mRadio = (ImageButton) findViewById(R.id.radio_onOrPause_button);
        mRadio_tv = (TextView) findViewById(R.id.radio_onOrPause_tv);
        mRadio.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                if (mRadio.getBackground().getConstantState() == getResources().getDrawable(R.drawable.radio_on1)
                        .getConstantState()) {
                    //?????
                    if (sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) {
                        mRadio.setBackgroundDrawable(getResources().getDrawable(R.drawable.radio_pause));
                    } else {
                        mRadio.setBackground(getResources().getDrawable(R.drawable.radio_pause));
                    }
                    mRadio_tv.setText("?");
                    play();
                } else {
                    //????
                    if (sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) {
                        mRadio.setBackgroundDrawable(getResources().getDrawable(R.drawable.radio_on1));
                    } else {
                        mRadio.setBackground(getResources().getDrawable(R.drawable.radio_on1));
                    }
                    mRadio_tv.setText("?");
                    pause();
                }
            }
        });

        mAudioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
        mAudioMax = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
        //
        mVoice = (ImageButton) findViewById(R.id.voice_overlay_button);
        mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, mAudioMax, 0);
        mVoice.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                if (mVoice.getBackground().getConstantState() == getResources().getDrawable(R.drawable.voice_on)
                        .getConstantState()) {
                    //??
                    if (sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) {
                        mVoice.setBackgroundDrawable(getResources().getDrawable(R.drawable.voice_off));
                    } else {
                        mVoice.setBackground(getResources().getDrawable(R.drawable.voice_off));
                    }
                    mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 0, 0);
                } else {
                    //??
                    if (sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) {
                        mVoice.setBackgroundDrawable(getResources().getDrawable(R.drawable.voice_on));
                    } else {
                        mVoice.setBackground(getResources().getDrawable(R.drawable.voice_on));
                    }
                    mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, mAudioMax, 0);
                }
            }
        });

        mSurface = (SurfaceView) findViewById(R.id.player_surface);
        mSurfaceHolder = mSurface.getHolder();
        mSurfaceFrame = (FrameLayout) findViewById(R.id.player_surface_frame);
        mSurfaceFrame.setOnTouchListener(new OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                // TODO Auto-generated method stub
                if (MotionEvent.ACTION_DOWN == event.getAction()) {
                    if (System.currentTimeMillis() - clickTime < 500) {
                        //??
                        if (mCurrentSize == SURFACE_4_3) {
                            //???
                            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
                        } else {
                            //??
                            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
                        }
                    } else {
                        if (!mShowing) {
                            showOverlay();
                            mSurfaceFrame.setFocusable(false);
                        } else {
                            hideOverlay(true);
                        }
                    }
                    clickTime = System.currentTimeMillis();
                    if (directionLayout.getVisibility() == View.INVISIBLE) {
                        directionLayout.setVisibility(View.VISIBLE);
                    } else {
                        directionLayout.setVisibility(View.INVISIBLE);
                    }
                }
                return true;
            }
        });

        mOrientationListener = new OrientationEventListener(this) {
            @Override
            public void onOrientationChanged(int rotation) {
                if (((rotation >= 0) && (rotation <= 45)) || (rotation >= 315)
                        || ((rotation >= 135) && (rotation <= 225))) {//portrait
                    mCurrentOrient = true;
                    if (mCurrentOrient != mScreenProtrait) {
                        mScreenProtrait = mCurrentOrient;
                        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
                        Log.d(TAG, "Screen orientation changed from Landscape to Portrait!");
                    }
                } else if (((rotation > 45) && (rotation < 135)) || ((rotation > 225) && (rotation < 315))) {//landscape
                    mCurrentOrient = false;
                    if (mCurrentOrient != mScreenProtrait) {
                        mScreenProtrait = mCurrentOrient;
                        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
                        Log.d(TAG, "Screen orientation changed from Portrait to Landscape!");
                    }
                }
            }
        };
        mOrientationListener.enable();

        int pitch;
        String chroma = pref.getString("chroma_format", "");
        if (Util.isGingerbreadOrLater() && chroma.equals("YV12")) {
            mSurfaceHolder.setFormat(ImageFormat.YV12);
            pitch = ImageFormat.getBitsPerPixel(ImageFormat.YV12) / 8;
        } else if (chroma.equals("RV16")) {
            mSurfaceHolder.setFormat(PixelFormat.RGB_565);
            PixelFormat info = new PixelFormat();
            PixelFormat.getPixelFormatInfo(PixelFormat.RGB_565, info);
            pitch = info.bytesPerPixel;
        } else {
            mSurfaceHolder.setFormat(PixelFormat.RGBX_8888);
            PixelFormat info = new PixelFormat();
            PixelFormat.getPixelFormatInfo(PixelFormat.RGBX_8888, info);
            pitch = info.bytesPerPixel;
        }
        mSurfaceAlign = 16 / pitch - 1;
        mSurfaceHolder.addCallback(mSurfaceCallback);

        mSeekbar = (SeekBar) findViewById(R.id.player_overlay_seekbar);
        mSeekbar.setOnSeekBarChangeListener(mSeekListener);

        mSwitchingView = false;
        mEndReached = false;

        // Clear the resume time, since it is only used for resumes in external
        // videos.
        SharedPreferences preferences = getSharedPreferences(PreferencesActivity.NAME, MODE_PRIVATE);
        SharedPreferences.Editor editor = preferences.edit();
        editor.putLong(PreferencesActivity.VIDEO_RESUME_TIME, -1);
        // Also clear the subs list, because it is supposed to be per session
        // only (like desktop VLC). We don't want the customs subtitle file
        // to persist forever with this video.
        editor.putString(PreferencesActivity.VIDEO_SUBTITLE_FILES, null);
        editor.commit();

        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_BATTERY_CHANGED);
        filter.addAction(VLCApplication.SLEEP_INTENT);
        registerReceiver(mReceiver, filter);

        try {
            mLibVLC = Util.getLibVlcInstance();
        } catch (LibVlcException e) {
            Log.d(TAG, "LibVLC initialisation failed");
            return;
        }

        EventHandler em = EventHandler.getInstance();
        em.addHandler(eventHandler);

        this.setVolumeControlStream(AudioManager.STREAM_MUSIC);

        // 100 is the value for screen_orientation_start_lock,??
        //        setRequestedOrientation(mScreenOrientation != 100
        //                ? mScreenOrientation
        //                : getScreenOrientation());

        //???
        //        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        //??
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    }

    @Override
    protected void onStart() {
        super.onStart();
        showOverlay();
        mSwitchingView = false;
    }

    @Override
    protected void onPause() {

        mOrientationListener.disable();
        //??
        videoScreenshot();
        super.onPause();

        if (mSwitchingView) {
            Log.d(TAG, "mLocation = \"" + mLocation + "\"");
            AudioServiceController.getInstance().showWithoutParse(savedIndexPosition);
            AudioServiceController.getInstance().unbindAudioService(this);
            //            AudioPlayerActivity.start(this, true);
            return;
        }

        long time = mLibVLC.getTime();
        long length = mLibVLC.getLength();
        //remove saved position if in the last 5 seconds
        if (length - time < 5000)
            time = 0;
        else
            time -= 5000; // go back 5 seconds, to compensate loading time

        /*
         * Pausing here generates errors because the vout is constantly
         * trying to refresh itself every 80ms while the surface is not
         * accessible anymore.
         * To workaround that, we keep the last known position in the playlist
         * in savedIndexPosition to be able to restore it during onResume().
         */
        if (savedIndexPosition >= 0)
            mLibVLC.stop();
        else {
            /* FIXME when the playback is started externally from AudioService
            * we don't have a savedIndexPosition. Use pause as a fallback until
            * we find a solution.
            */
            mLibVLC.pause();
        }

        mSurface.setKeepScreenOn(false);

        SharedPreferences preferences = getSharedPreferences(PreferencesActivity.NAME, MODE_PRIVATE);
        SharedPreferences.Editor editor = preferences.edit();
        // Save position
        if (time >= 0) {
            if (MediaDatabase.getInstance(this).mediaItemExists(mLocation)) {
                editor.putString(PreferencesActivity.LAST_MEDIA, mLocation);
                MediaDatabase.getInstance(this).updateMedia(mLocation, MediaDatabase.mediaColumn.MEDIA_TIME, time);
            } else {
                // Video file not in media library, store time just for onResume()
                editor.putLong(PreferencesActivity.VIDEO_RESUME_TIME, time);
            }
        }
        // Save selected subtitles
        String subtitleList_serialized = null;
        if (mSubtitleSelectedFiles.size() > 0) {
            Log.d(TAG, "Saving selected subtitle files");
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            try {
                ObjectOutputStream oos = new ObjectOutputStream(bos);
                oos.writeObject(mSubtitleSelectedFiles);
                subtitleList_serialized = bos.toString();
            } catch (IOException e) {
            }
        }
        editor.putString(PreferencesActivity.VIDEO_SUBTITLE_FILES, subtitleList_serialized);

        editor.commit();
        AudioServiceController.getInstance().unbindAudioService(this);
    }

    @Override
    protected void onStop() {
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(mReceiver);
        if (mLibVLC != null && !mSwitchingView) {
            mLibVLC.stop();
        }

        EventHandler em = EventHandler.getInstance();
        em.removeHandler(eventHandler);

        mAudioManager = null;

    }

    @Override
    protected void onResume() {
        super.onResume();
        //Begin delete share image
        //End delete share image

        AudioServiceController.getInstance().bindAudioService(this);
        load();
        /*
         * if the activity has been paused by pressing the power button,
         * pressing it again will show the lock screen.
         * But onResume will also be called, even if vlc-android is still in the background.
         * To workaround that, pause playback if the lockscreen is displayed
         */
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                if (mLibVLC != null && mLibVLC.isPlaying()) {
                    KeyguardManager km = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
                    if (km.inKeyguardRestrictedInputMode())
                        mLibVLC.pause();
                }
            }
        }, 500);

        showOverlay();

        // Add any selected subtitle file from the file picker
        if (mSubtitleSelectedFiles.size() > 0) {
            for (String file : mSubtitleSelectedFiles) {
                Log.i(TAG, "Adding user-selected subtitle " + file);
                mLibVLC.addSubtitleTrack(file);
            }
            /** FIXME remove when #7540 ES are not updated mid-stream
            *  a.k.a. subtitle events is fixed
            */
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    setESTrackLists(true);

                    mHandler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            setESTrackLists(true);
                        }
                    }, 1200);
                }
            }, 1000);
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (data == null)
            return;

        if (data.getDataString() == null) {
            Log.d(TAG, "Subtitle selection dialog was cancelled");
        }
        if (data.getData() == null)
            return;

        String uri = data.getData().getPath();
        mSubtitleSelectedFiles.add(data.getData().getPath());

    }

    private void retry() {
        if (mLibVLC != null) {
            mLibVLC.stop();
            savedIndexPosition = mLibVLC.readMedia(mLocation, false);
            mRetry++;
        }
    }

    public static void start(Context context, String location) {
        start(context, location, null, -1, false, false, false);
    }

    public static void start(Context context, String location, Boolean fromStart) {
        start(context, location, null, -1, false, fromStart, false);
    }

    public static void start(Context context, String location, String title, Boolean dontParse) {
        start(context, location, title, -1, dontParse, false, false);
    }

    public static void start(Context context, String location, String title, int position, Boolean dontParse) {
        start(context, location, title, position, dontParse, false, false);
    }

    public static void start(Context context, String location, String title, int position, Boolean dontParse,
            Boolean fromStart, Boolean useStun) {
        //VideoPlayerActivity.cameraId=cameraid;
        if (ActivityDevice.current_camID != -1)
            cameraId = ActivityDevice.current_camID;
        else
            cameraId = ActivityShiPin.current_camID;
        Intent intent = new Intent(context, VideoPlayerActivity.class);
        intent.setAction(VideoPlayerActivity.PLAY_FROM_VIDEOGRID);
        intent.putExtra("itemLocation", location);
        intent.putExtra("itemTitle", title);
        intent.putExtra("dontParse", dontParse);
        intent.putExtra("fromStart", fromStart);
        intent.putExtra("useStun", useStun);
        intent.putExtra("itemPosition", position);

        if (dontParse)
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
        else {
            // Stop the currently running audio
            AudioServiceController asc = AudioServiceController.getInstance();
            asc.stop();
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
        }

        context.startActivity(intent);
    }

    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equalsIgnoreCase(Intent.ACTION_BATTERY_CHANGED)) {
                int batteryLevel = intent.getIntExtra("level", 0);
                if (batteryLevel >= 50)
                    mBattery.setTextColor(Color.GREEN);
                else if (batteryLevel >= 30)
                    mBattery.setTextColor(Color.YELLOW);
                else
                    mBattery.setTextColor(Color.RED);
                mBattery.setText(String.format("%d%%", batteryLevel));
            } else if (action.equalsIgnoreCase(VLCApplication.SLEEP_INTENT)) {
                finish();
            }
        }
    };

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        setSurfaceSize(mVideoWidth, mVideoHeight, mVideoVisibleWidth, mVideoVisibleHeight, mSarNum, mSarDen);

        //??
        if (mCurrentSize == SURFACE_4_3) {
            mCurrentSize = SURFACE_ORIGINAL;
            mOverlayLock.setVisibility(View.GONE);
        } else {
            mCurrentSize = SURFACE_4_3;
            mOverlayLock.setVisibility(View.VISIBLE);
        }
        changeSurfaceSize();
        super.onConfigurationChanged(newConfig);
    }

    @Override
    public void setSurfaceSize(int width, int height, int visible_width, int visible_height, int sar_num,
            int sar_den) {
        if (width * height == 0)
            return;

        // store video size

        mVideoHeight = height;
        mVideoWidth = width;
        mVideoVisibleHeight = visible_height;
        mVideoVisibleWidth = visible_width;
        mSarNum = sar_num;
        mSarDen = sar_den;
        Message msg = mHandler.obtainMessage(SURFACE_SIZE);
        mHandler.sendMessage(msg);
    }

    /**
     * Lock screen rotation
     */
    private void lockScreen() {
        if (mScreenOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR)
            setRequestedOrientation(getScreenOrientation());
        showInfo(R.string.locked, 1000);
        mLock.setBackgroundResource(R.drawable.screen_lock_on);
        mTime.setEnabled(false);
        mSeekbar.setEnabled(false);
        mLength.setEnabled(false);
        hideOverlay(true);
    }

    /**
     * Remove screen lock
     */
    private void unlockScreen() {
        if (mScreenOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR)
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
        showInfo(R.string.unlocked, 1000);
        mLock.setBackgroundResource(R.drawable.screen_lock_off);
        mTime.setEnabled(true);
        mSeekbar.setEnabled(true);
        mLength.setEnabled(true);
        mShowing = false;
        showOverlay();
    }

    /**
     * Show text in the info view for "duration" milliseconds
     * @param text
     * @param duration
     */
    private void showInfo(String text, int duration) {
        mInfo.setVisibility(View.VISIBLE);
        mInfo.setText(text);
        mHandler.removeMessages(FADE_OUT_INFO);
        mHandler.sendEmptyMessageDelayed(FADE_OUT_INFO, duration);
    }

    private void showInfo(int textid, int duration) {
        mInfo.setVisibility(View.VISIBLE);
        mInfo.setText(textid);
        mHandler.removeMessages(FADE_OUT_INFO);
        mHandler.sendEmptyMessageDelayed(FADE_OUT_INFO, duration);
    }

    /**
     * Show text in the info view
     * @param text
     */
    private void showInfo(String text) {
        mInfo.setVisibility(View.VISIBLE);
        mInfo.setText(text);
        mHandler.removeMessages(FADE_OUT_INFO);
    }

    /**
     * hide the info view with "delay" milliseconds delay
     * @param delay
     */
    private void hideInfo(int delay) {
        mHandler.sendEmptyMessageDelayed(FADE_OUT_INFO, delay);
    }

    /**
     * hide the info view
     */
    private void hideInfo() {
        hideInfo(0);
    }

    private void fadeOutInfo() {
        if (mInfo.getVisibility() == View.VISIBLE)
            mInfo.startAnimation(AnimationUtils.loadAnimation(VideoPlayerActivity.this, android.R.anim.fade_out));
        mInfo.setVisibility(View.INVISIBLE);
    }

    /**
     *  Handle libvlc asynchronous events
     */
    private final Handler eventHandler = new VideoPlayerEventHandler(this);

    private static class VideoPlayerEventHandler extends WeakHandler<VideoPlayerActivity> {
        public VideoPlayerEventHandler(VideoPlayerActivity owner) {
            super(owner);
        }

        @Override
        public void handleMessage(Message msg) {
            VideoPlayerActivity activity = getOwner();
            if (activity == null)
                return;

            switch (msg.getData().getInt("event")) {
            case EventHandler.MediaPlayerPlaying:
                Log.i(TAG, "MediaPlayerPlaying");
                activity.play_lay.setVisibility(View.VISIBLE);
                activity.progress_lay.setVisibility(View.GONE);
                activity.setESTracks();
                break;
            case EventHandler.MediaPlayerPaused:
                Log.i(TAG, "MediaPlayerPaused");
                break;
            case EventHandler.MediaPlayerStopped:
                Log.i(TAG, "MediaPlayerStopped");
                break;
            case EventHandler.MediaPlayerEndReached:
                Log.i(TAG, "MediaPlayerEndReached");
                activity.endReached();
                break;
            case EventHandler.MediaPlayerVout:
                activity.handleVout(msg);
                break;
            case EventHandler.MediaPlayerRecordableChanged:
                break;
            case EventHandler.MediaPlayerRecordingFinished:
                Log.d(TAG, "record file is" + msg.getData().getString("data"));
                break;
            case EventHandler.MediaPlayerPositionChanged:
                //don't spam the logs
                break;
            case EventHandler.MediaPlayerEncounteredError:
                Log.i(TAG, "MediaPlayerEncounteredError");
                activity.encounteredError();
                break;
            default:
                Log.e(TAG, String.format("Event not handled (0x%x)", msg.getData().getInt("event")));
                break;
            }
            activity.updateOverlayPausePlay();
        }
    };

    /**
     * Handle resize of the surface and the overlay
     */
    private final Handler mHandler = new VideoPlayerHandler(this);

    private static class VideoPlayerHandler extends WeakHandler<VideoPlayerActivity> {
        public VideoPlayerHandler(VideoPlayerActivity owner) {
            super(owner);
        }

        @Override
        public void handleMessage(Message msg) {
            VideoPlayerActivity activity = getOwner();
            if (activity == null) // WeakReference could be GC'ed early
                return;

            switch (msg.what) {
            case FADE_OUT:
                activity.hideOverlay(false);
                break;
            case SHOW_PROGRESS:
                int pos = activity.setOverlayProgress();
                if (activity.canShowProgress()) {
                    msg = obtainMessage(SHOW_PROGRESS);
                    sendMessageDelayed(msg, 1000 - (pos % 1000));
                }
                break;
            case SURFACE_SIZE:
                activity.changeSurfaceSize();
                break;
            case FADE_OUT_INFO:
                activity.fadeOutInfo();
                break;
            }
        }
    };

    private boolean canShowProgress() {
        return !mDragging && mShowing && mLibVLC.isPlaying();
    }

    private void endReached() {
        /* Exit player when reach the end */
        mEndReached = true;
        String title = "?";
        String message = "??";
        ShowNotifyDialog mDialog = new ShowNotifyDialog(VideoPlayerActivity.this, R.style.myDialogTheme, title,
                message);
        mDialog.setOnSureClick("", new ShowNotifyDialog.OnSureClick() {

            @Override
            public void onClick(View view) {
                // TODO Auto-generated method stub
                finish();
            }
        });
        mDialog.show();
        //       }
    }

    private void encounteredError() {
        /* Encountered Error, exit player with a message */
        mRetry++;
        if (mRetry < mRetryMax) {
            if (mRetry == 1) {
                System.out.println("mRetry mRetry mRetry = " + mRetry);
                if (!Constant.localPlayUrl.equals(Constant.upnpPlayUrl)) {
                    mTitle.setText(Constant.upnpPlayUrl);
                    savedIndexPosition = mLibVLC.readMedia(Constant.upnpPlayUrl, false);
                } else {
                    mRetry++;
                    System.out.println("mRetry mRetry mRetry = " + mRetry);
                    mTitle.setText(Constant.turnPlayUrl);
                    savedIndexPosition = mLibVLC.readMedia(Constant.turnPlayUrl, false);
                }

            } else if (mRetry == 2) {
                System.out.println("mRetry mRetry mRetry = " + mRetry);
                mTitle.setText(Constant.turnPlayUrl);
                savedIndexPosition = mLibVLC.readMedia(Constant.turnPlayUrl, false);
            }
        } else {
            String title = this.getResources().getString(R.string.encountered_error_title);
            String message = this.getResources().getString(R.string.encountered_error_message);
            ShowNotifyDialog mDialog = new ShowNotifyDialog(VideoPlayerActivity.this, R.style.myDialogTheme, title,
                    message);
            mDialog.setOnSureClick("", new ShowNotifyDialog.OnSureClick() {

                @Override
                public void onClick(View view) {
                    // TODO Auto-generated method stub
                    System.out.println("mRetry mRetry mRetry = " + mRetry);
                    finish();
                }
            });
            mDialog.show();
        }

    }

    private void handleVout(Message msg) {
        if (msg.getData().getInt("data") == 0 && !mEndReached) {
            /* Video track lost, open in audio mode */
            Log.i(TAG, "Video track lost, switching to audio");
            mSwitchingView = true;
            //            finish();
            String title = this.getResources().getString(R.string.encountered_error_title);
            String message = this.getResources().getString(R.string.encountered_error_message);
            ShowNotifyDialog mDialog = new ShowNotifyDialog(VideoPlayerActivity.this, R.style.myDialogTheme, title,
                    message);
            mDialog.setOnSureClick("", new ShowNotifyDialog.OnSureClick() {

                @Override
                public void onClick(View view) {
                    // TODO Auto-generated method stub
                    finish();
                }
            });
            mDialog.show();
        }
    }

    private void changeSurfaceSize() {
        // get screen size
        int dw = getWindow().getDecorView().getWidth();
        int dh = getWindow().getDecorView().getHeight();

        // getWindow().getDecorView() doesn't always take orientation into account, we have to correct the values
        boolean isPortrait = getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
        if (dw > dh && isPortrait || dw < dh && !isPortrait) {
            int d = dw;
            dw = dh;
            dh = d;
        }

        // sanity check
        if (dw * dh == 0 || mVideoWidth * mVideoHeight == 0) {
            Log.e(TAG, "Invalid surface size");
            return;
        }

        // compute the aspect ratio
        double ar, vw;
        double density = (double) mSarNum / (double) mSarDen;
        if (density == 1.0) {
            /* No indication about the density, assuming 1:1 */
            vw = mVideoWidth;
            ar = (double) mVideoWidth / (double) mVideoHeight;
        } else {
            /* Use the specified aspect ratio */
            vw = mVideoWidth * density;
            ar = vw / mVideoHeight;
        }

        // compute the display aspect ratio
        double dar = (double) dw / (double) dh;

        switch (mCurrentSize) {
        case SURFACE_BEST_FIT:
            if (dar < ar)
                dh = (int) (dw / ar);
            else
                dw = (int) (dh * ar);
            break;
        case SURFACE_FIT_HORIZONTAL:
            dh = (int) (dw / ar);
            break;
        case SURFACE_FIT_VERTICAL:
            dw = (int) (dh * ar);
            break;
        case SURFACE_FILL:
            break;
        case SURFACE_16_9:
            ar = 16.0 / 9.0;
            if (dar < ar)
                dh = (int) (dw / ar);
            else
                dw = (int) (dh * ar);
            break;
        case SURFACE_4_3:
            ar = 4.0 / 3.0;
            if (dar < ar)
                dh = (int) (dw / ar);
            else
                dw = (int) (dh * ar);
            break;
        case SURFACE_ORIGINAL:
            ar = 16.0 / 9.0;
            if (dar < ar)
                dh = (int) (dw / ar);
            else
                dw = (int) (dh * ar);
            break;
        }

        // align width on 16bytes
        int alignedWidth = (mVideoWidth + mSurfaceAlign) & ~mSurfaceAlign;

        // force surface buffer size
        mSurfaceHolder.setFixedSize(alignedWidth, mVideoHeight);

        // set display size
        LayoutParams lp = mSurface.getLayoutParams();
        lp.width = dw * alignedWidth / mVideoWidth;
        lp.height = dh;
        mSurface.setLayoutParams(lp);

        // set frame size (crop if necessary)
        //        lp = mSurfaceFrame.getLayoutParams();
        //        lp.width = dw;
        //        lp.height = dh;
        //        mSurfaceFrame.setLayoutParams(lp);
        FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) mSurfaceFrame.getLayoutParams();
        params.width = dw;
        params.height = dh;
        if (mCurrentSize == SURFACE_ORIGINAL) {
            params.topMargin = 0;
            params.gravity = Gravity.CENTER;
        } else {
            params.topMargin = (int) getResources().getDimension(R.dimen.video_padding_top);
            params.gravity = Gravity.CENTER_HORIZONTAL;
        }
        ;
        mSurfaceFrame.setLayoutParams(params);

        mSurface.invalidate();
    }

    /**
     * show/hide the overlay
     */

    //    @Override
    //    public boolean onTouchEvent(MotionEvent event) {
    //        if (mIsLocked) {
    //            showOverlay();
    //            return false;
    //        }
    //        
    //        DisplayMetrics screen = new DisplayMetrics();
    //        getWindowManager().getDefaultDisplay().getMetrics(screen);
    //
    //        if (mSurfaceYDisplayRange == 0)
    //            mSurfaceYDisplayRange = Math.min(screen.widthPixels, screen.heightPixels);
    //
    //        float y_changed = event.getRawY() - mTouchY;
    //        float x_changed = event.getRawX() - mTouchX;
    //
    //        // coef is the gradient's move to determine a neutral zone
    //        float coef = Math.abs (y_changed / x_changed);
    //        float xgesturesize = ((x_changed / screen.xdpi) * 2.54f);
    //
    //        switch (event.getAction()) {
    //
    //        case MotionEvent.ACTION_DOWN:
    //            // Audio
    //            mTouchY = event.getRawY();
    //            mVol = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
    //            mIsAudioOrBrightnessChanged = false;
    //            // Seek
    //            mTouchX = event.getRawX();
    //            break;
    //
    //        case MotionEvent.ACTION_MOVE:
    //            // No volume/brightness action if coef < 2
    //            if (coef > 2) {
    //                // Volume (Up or Down - Right side)
    //                if (!mEnableBrightnessGesture || mTouchX > (screen.widthPixels / 2)){
    //                    doVolumeTouch(y_changed);
    //                }
    //                // Brightness (Up or Down - Left side)
    //                if (mEnableBrightnessGesture && mTouchX < (screen.widthPixels / 2)){
    //                    doBrightnessTouch(y_changed);
    //                }
    //                // Extend the overlay for a little while, so that it doesn't
    //                // disappear on the user if more adjustment is needed. This
    //                // is because on devices with soft navigation (e.g. Galaxy
    //                // Nexus), gestures can't be made without activating the UI.
    //                if(Util.hasNavBar())
    //                    showOverlay();
    //            }
    //            // Seek (Right or Left move)
    //            doSeekTouch(coef, xgesturesize, false);
    //            break;
    //
    //        case MotionEvent.ACTION_UP:
    //            // Audio or Brightness
    //            if (!mIsAudioOrBrightnessChanged) {
    //                if (!mShowing) {
    //                    showOverlay();
    //                } else {
    //                    hideOverlay(true);
    //                }
    //            }
    //            // Seek
    //            doSeekTouch(coef, xgesturesize, true);
    //            break;
    //        }
    //        return mIsAudioOrBrightnessChanged;
    //    }

    private void doSeekTouch(float coef, float gesturesize, boolean seek) {
        // No seek action if coef > 0.5 and gesturesize < 1cm
        if (mEnableWheelbar || coef > 0.5 || Math.abs(gesturesize) < 1)
            return;

        // Always show seekbar when searching
        if (!mShowing)
            showOverlay();

        long length = mLibVLC.getLength();
        long time = mLibVLC.getTime();

        // Size of the jump, 10 minutes max (600000), with a bi-cubic progression, for a 8cm gesture
        int jump = (int) (Math.signum(gesturesize) * ((600000 * Math.pow((gesturesize / 8), 4)) + 3000));

        // Adjust the jump
        if ((jump > 0) && ((time + jump) > length))
            jump = (int) (length - time);
        if ((jump < 0) && ((time + jump) < 0))
            jump = (int) -time;

        //Jump !
        if (seek)
            mPlayerControlListener.onSeekTo(time + jump);

        //Show the jump's size
        showInfo(String.format("%s%s (%s)", jump >= 0 ? "+" : "", Util.millisToString(jump),
                Util.millisToString(time + jump)), 1000);
    }

    private void doVolumeTouch(float y_changed) {
        int delta = -(int) ((y_changed / mSurfaceYDisplayRange) * mAudioMax);
        int vol = (int) Math.min(Math.max(mVol + delta, 0), mAudioMax);
        if (delta != 0) {
            mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, vol, 0);
            mIsAudioOrBrightnessChanged = true;
            showInfo(getString(R.string.volume) + '\u00A0' + Integer.toString(vol), 1000);
        }
    }

    private void initBrightnessTouch() {
        float brightnesstemp = 0.01f;
        // Initialize the layoutParams screen brightness
        try {
            brightnesstemp = android.provider.Settings.System.getInt(getContentResolver(),
                    android.provider.Settings.System.SCREEN_BRIGHTNESS) / 255.0f;
        } catch (SettingNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        WindowManager.LayoutParams lp = getWindow().getAttributes();
        lp.screenBrightness = brightnesstemp;
        getWindow().setAttributes(lp);
        mIsFirstBrightnessGesture = false;
    }

    private void doBrightnessTouch(float y_changed) {
        if (mIsFirstBrightnessGesture)
            initBrightnessTouch();
        mIsAudioOrBrightnessChanged = true;

        // Set delta : 0.07f is arbitrary for now, it possibly will change in the future
        float delta = -y_changed / mSurfaceYDisplayRange * 0.07f;

        // Estimate and adjust Brightness
        WindowManager.LayoutParams lp = getWindow().getAttributes();
        lp.screenBrightness = Math.min(Math.max(lp.screenBrightness + delta, 0.01f), 1);

        // Set Brightness
        getWindow().setAttributes(lp);
        showInfo(getString(R.string.brightness) + '\u00A0' + Math.round(lp.screenBrightness * 15), 1000);
    }

    /**
     * handle changes of the seekbar (slicer)
     */
    private final OnSeekBarChangeListener mSeekListener = new OnSeekBarChangeListener() {

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
            mDragging = true;
            showOverlay(OVERLAY_INFINITE);
        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
            mDragging = false;
            showOverlay();
            hideInfo();
        }

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            if (fromUser) {
                mLibVLC.setTime(progress);
                setOverlayProgress();
                mTime.setText(Util.millisToString(progress));
                showInfo(Util.millisToString(progress));
            }

        }
    };

    /**
     *
     */
    private final OnClickListener mAudioTrackListener = new OnClickListener() {
        @Override
        public void onClick(View v) {
            final String[] arrList = new String[mAudioTracksList.size()];
            int i = 0;
            int listPosition = 0;
            for (Map.Entry<Integer, String> entry : mAudioTracksList.entrySet()) {
                arrList[i] = entry.getValue();
                // map the track position to the list position
                if (entry.getKey() == mLibVLC.getAudioTrack())
                    listPosition = i;
                i++;
            }
            AlertDialog dialog = new AlertDialog.Builder(VideoPlayerActivity.this).setTitle(R.string.track_audio)
                    .setSingleChoiceItems(arrList, listPosition, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int listPosition) {
                            int trackID = -1;
                            // Reverse map search...
                            for (Map.Entry<Integer, String> entry : mAudioTracksList.entrySet()) {
                                if (arrList[listPosition].equals(entry.getValue())) {
                                    trackID = entry.getKey();
                                    break;
                                }
                            }
                            if (trackID < 0)
                                return;

                            MediaDatabase.getInstance(VideoPlayerActivity.this).updateMedia(mLocation,
                                    MediaDatabase.mediaColumn.MEDIA_AUDIOTRACK, trackID);
                            mLibVLC.setAudioTrack(trackID);
                            dialog.dismiss();
                        }
                    }).create();
            dialog.setCanceledOnTouchOutside(true);
            dialog.setOwnerActivity(VideoPlayerActivity.this);
            dialog.show();
        }
    };

    /**
     *
     */
    private final OnClickListener mSubtitlesListener = new OnClickListener() {
        @Override
        public void onClick(View v) {
            final String[] arrList = new String[mSubtitleTracksList.size()];
            int i = 0;
            int listPosition = 0;
            for (Map.Entry<Integer, String> entry : mSubtitleTracksList.entrySet()) {
                arrList[i] = entry.getValue();
                // map the track position to the list position
                if (entry.getKey() == mLibVLC.getSpuTrack())
                    listPosition = i;
                i++;
            }

            AlertDialog dialog = new AlertDialog.Builder(VideoPlayerActivity.this).setTitle(R.string.track_text)
                    .setSingleChoiceItems(arrList, listPosition, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int listPosition) {
                            int trackID = -2;
                            // Reverse map search...
                            for (Map.Entry<Integer, String> entry : mSubtitleTracksList.entrySet()) {
                                if (arrList[listPosition].equals(entry.getValue())) {
                                    trackID = entry.getKey();
                                    break;
                                }
                            }
                            if (trackID < -1)
                                return;

                            MediaDatabase.getInstance(VideoPlayerActivity.this).updateMedia(mLocation,
                                    MediaDatabase.mediaColumn.MEDIA_SPUTRACK, trackID);
                            mLibVLC.setSpuTrack(trackID);
                            dialog.dismiss();
                        }
                    }).create();
            dialog.setCanceledOnTouchOutside(true);
            dialog.setOwnerActivity(VideoPlayerActivity.this);
            dialog.show();
        }
    };

    /**
     *
     */
    private final OnPlayerControlListener mPlayerControlListener = new OnPlayerControlListener() {
        @Override
        public void onPlayPause() {
            if (mLibVLC.isPlaying())
                pause();
            else
                play();
            showOverlay();
        }

        @Override
        public void onSeek(int delta) {
            // unseekable stream
            if (mLibVLC.getLength() <= 0)
                return;

            long position = mLibVLC.getTime() + delta;
            if (position < 0)
                position = 0;
            mLibVLC.setTime(position);
            showOverlay();
        }

        @Override
        public void onSeekTo(long position) {
            // unseekable stream
            if (mLibVLC.getLength() <= 0)
                return;
            mLibVLC.setTime(position);
            mTime.setText(Util.millisToString(position));
        }

        @Override
        public long onWheelStart() {
            showOverlay(OVERLAY_INFINITE);
            return mLibVLC.getTime();
        }

        @Override
        public void onShowInfo(String info) {
            if (info != null)
                showInfo(info);
            else {
                hideInfo();
                showOverlay();
            }
        }
    };

    /**
     *
     */
    private final OnClickListener mLockListener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            if (mIsLocked) {
                mIsLocked = false;
                unlockScreen();
            } else {
                mIsLocked = true;
                lockScreen();
            }
        }
    };

    /**
     *
     */
    private final OnClickListener mSizeListener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            if (mCurrentSize == SURFACE_4_3) {
                mCurrentSize = SURFACE_ORIGINAL;
                mOverlayLock.setVisibility(View.GONE);
                //???
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
            } else {
                mCurrentSize = SURFACE_4_3;
                mOverlayLock.setVisibility(View.VISIBLE);
                //??
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
            }
            changeSurfaceSize();
            showOverlay();
        }
    };

    private final OnClickListener mRemainingTimeListener = new OnClickListener() {
        @Override
        public void onClick(View v) {
            mDisplayRemainingTime = !mDisplayRemainingTime;
            showOverlay();
        }
    };

    /**
     *
     */
    private final OnClickListener mSnapShotListener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            boolean snapRest = mLibVLC.takeSnapShot("/sdcard/snapShot.png", mVideoWidth, mVideoHeight);
            Log.d(TAG, "Snap shot res is " + snapRest);
        }
    };
    private final OnClickListener mRecordingListener = new OnClickListener() {
        @Override
        public void onClick(View v) {
            if (mLibVLC.videoIsRecording() && mRecording) {
                boolean recordStop = mLibVLC.videoRecordStop();
                mRecording = false;
                mRecord.setBackgroundResource(R.drawable.record_start);
                mRecord.setOnClickListener(mRecordListener);
                Log.d(TAG, "videoRecordStop res is " + recordStop);
            } else {
                Log.d(TAG, "video record is not starting");
            }
        }
    };

    private final OnClickListener mRecordListener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            if (mLibVLC.videoIsRecordable() && !mLibVLC.videoIsRecording() && !mRecording) {
                boolean recordStart = mLibVLC.videoRecordStart("/sdcard/record");
                mRecording = true;
                mRecord.setBackgroundResource(R.drawable.record_end);
                mRecord.setOnClickListener(mRecordingListener);
                Log.d(TAG, "videoRecordStart res is " + recordStart);
            } else {
                Log.d(TAG, "video record can not start");
            }

        }
    };
    /**
     * attach and disattach surface to the lib
     */
    private final SurfaceHolder.Callback mSurfaceCallback = new Callback() {
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            if (format == PixelFormat.RGBX_8888)
                Log.d(TAG, "Pixel format is RGBX_8888");
            else if (format == PixelFormat.RGB_565)
                Log.d(TAG, "Pixel format is RGB_565");
            else if (format == ImageFormat.YV12)
                Log.d(TAG, "Pixel format is YV12");
            else
                Log.d(TAG, "Pixel format is other/unknown");
            mLibVLC.attachSurface(holder.getSurface(), VideoPlayerActivity.this, width, height);
        }

        @Override
        public void surfaceCreated(SurfaceHolder holder) {
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            mLibVLC.detachSurface();
        }
    };

    /**
     * show overlay the the default timeout
     */
    private void showOverlay() {
        showOverlay(OVERLAY_TIMEOUT);
    }

    /**
     * show overlay
     */
    private void showOverlay(int timeout) {
        mHandler.sendEmptyMessage(SHOW_PROGRESS);
        if (!mShowing) {
            mShowing = true;
            if (!mIsLocked) {
                mOverlayOption.setVisibility(View.INVISIBLE);
            }
        }
        Message msg = mHandler.obtainMessage(FADE_OUT);
        if (timeout != 0) {
            mHandler.removeMessages(FADE_OUT);
            mHandler.sendMessageDelayed(msg, timeout);
        }
        updateOverlayPausePlay();
    }

    /**
     * hider overlay
     */
    private void hideOverlay(boolean fromUser) {
        if (mShowing) {
            mHandler.removeMessages(SHOW_PROGRESS);
            Log.i(TAG, "remove View!");
            if (!fromUser && !mIsLocked) {
                //                mOverlayLock.startAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_out));
                //                mOverlayHeader.startAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_out));
                //                mOverlayOption.startAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_out));
                //                mOverlayProgress.startAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_out));
                //                mOverlayInterface.startAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_out));

            }
            //            mOverlayLock.setVisibility(View.INVISIBLE);
            //            mOverlayHeader.setVisibility(View.INVISIBLE);
            //            mOverlayOption.setVisibility(View.INVISIBLE);
            //            mOverlayProgress.setVisibility(View.INVISIBLE);
            //            mOverlayInterface.setVisibility(View.INVISIBLE);
            mShowing = false;
            //            dimStatusBar(true);
        }
    }

    /**
     * Dim the status bar and/or navigation icons when needed on Android 3.x.
     * Hide it on Android 4.0 and later
     */
    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    private void dimStatusBar(boolean dim) {
        if (!Util.isHoneycombOrLater() || !Util.hasNavBar())
            return;
        mSurface.setSystemUiVisibility(
                dim ? (Util.hasCombBar() ? View.SYSTEM_UI_FLAG_LOW_PROFILE : View.SYSTEM_UI_FLAG_HIDE_NAVIGATION)
                        : View.SYSTEM_UI_FLAG_VISIBLE);
    }

    private void updateOverlayPausePlay() {
        if (mLibVLC == null) {
            return;
        }

        mControls.setState(mLibVLC.isPlaying());
    }

    /**
     * update the overlay
     */
    private int setOverlayProgress() {
        if (mLibVLC == null) {
            return 0;
        }
        int time = (int) mLibVLC.getTime();
        int length = (int) mLibVLC.getLength();
        // Update all view elements

        mControls.setSeekable(length > 0);
        mSeekbar.setMax(length);
        mSeekbar.setProgress(time);
        mSysTime.setText(DateFormat.getTimeFormat(this).format(new Date(System.currentTimeMillis())));
        mTime.setText(Util.millisToString(time));
        mLength.setText(mDisplayRemainingTime && length > 0 ? "- " + Util.millisToString(length - time)
                : Util.millisToString(length));

        return time;
    }

    private void setESTracks() {
        if (mLastAudioTrack >= 0) {
            mLibVLC.setAudioTrack(mLastAudioTrack);
            mLastAudioTrack = -1;
        }
        if (mLastSpuTrack >= -1) {
            mLibVLC.setSpuTrack(mLastSpuTrack);
            mLastSpuTrack = -2;
        }
    }

    private void setESTrackLists() {
        setESTrackLists(false);
    }

    private void setESTrackLists(boolean force) {
        if (mAudioTracksList == null || force) {
            if (mLibVLC.getAudioTracksCount() > 2) {
                mAudioTracksList = mLibVLC.getAudioTrackDescription();
                mAudioTrack.setOnClickListener(mAudioTrackListener);
                mAudioTrack.setVisibility(View.VISIBLE);
            } else {
                mAudioTrack.setVisibility(View.GONE);
                mAudioTrack.setOnClickListener(null);
            }
        }
        if (mSubtitleTracksList == null || force) {
            if (mLibVLC.getSpuTracksCount() > 0) {
                mSubtitleTracksList = mLibVLC.getSpuTrackDescription();
                mSubtitle.setOnClickListener(mSubtitlesListener);
                mSubtitle.setVisibility(View.VISIBLE);
            } else {
                mSubtitle.setVisibility(View.GONE);
                mSubtitle.setOnClickListener(null);
            }
        }
    }

    /**
     *
     */
    private void play() {
        mLibVLC.play();
        mSurface.setKeepScreenOn(true);
    }

    /**
     *
     */
    private void pause() {
        mLibVLC.pause();
        mSurface.setKeepScreenOn(false);
    }

    /**
     * External extras:
     * - position (long) - position of the video to start with (in ms)
     */
    @SuppressWarnings({ "deprecation", "unchecked" })
    private void load() {
        mLocation = null;
        String title = getResources().getString(R.string.title);
        boolean dontParse = false;
        boolean fromStart = false;
        String itemTitle = null;
        long intentPosition = -1; // position passed in by intent (ms)
        boolean useStun = false;

        if (getIntent().getAction() != null && getIntent().getAction().equals(Intent.ACTION_VIEW)) {
            /* Started from external application */
            if (getIntent().getData() != null && getIntent().getData().getScheme() != null
                    && getIntent().getData().getScheme().equals("content")) {
                if (getIntent().getData().getHost().equals("media")) {
                    // Media URI
                    Cursor cursor = managedQuery(getIntent().getData(), new String[] { MediaColumns.DATA }, null,
                            null, null);
                    int column_index = cursor.getColumnIndexOrThrow(MediaColumns.DATA);
                    if (cursor.moveToFirst())
                        mLocation = LibVLC.PathToURI(cursor.getString(column_index));
                } else {
                    // other content-based URI (probably file pickers)
                    mLocation = getIntent().getData().getPath();
                }
            } else {
                // Plain URI
                mLocation = getIntent().getDataString();
            }
            if (getIntent().getExtras() != null)
                intentPosition = getIntent().getExtras().getLong("position", -1);
        } else if (getIntent().getAction() != null && getIntent().getAction().equals(PLAY_FROM_VIDEOGRID)
                && getIntent().getExtras() != null) {
            /* Started from VideoListActivity */
            mLocation = getIntent().getExtras().getString("itemLocation");
            itemTitle = getIntent().getExtras().getString("itemTitle");
            dontParse = getIntent().getExtras().getBoolean("dontParse");
            fromStart = getIntent().getExtras().getBoolean("fromStart");
            useStun = getIntent().getExtras().getBoolean("useStun");
        }

        mSurface.setKeepScreenOn(true);

        /* Start / resume playback */
        if (savedIndexPosition > -1) {
            mLibVLC.playIndex(savedIndexPosition);
        } else if (mLocation != null && mLocation.length() > 0 && !dontParse) {
            if (useStun) {
                mLibVLC.setStunServerAddr("192.168.36.124");
                mLibVLC.setStunServerPort(3478);
                savedIndexPosition = mLibVLC.readMediaUseStun(mLocation, false);
            } else {
                savedIndexPosition = mLibVLC.readMedia(mLocation, false);
            }
        }

        if (mLocation != null && mLocation.length() > 0 && !dontParse) {
            // restore last position
            SharedPreferences preferences = getSharedPreferences(PreferencesActivity.NAME, MODE_PRIVATE);
            Media media = MediaDatabase.getInstance(this).getMedia(this, mLocation);
            if (media != null) {
                // in media library
                if (media.getTime() > 0 && !fromStart)
                    mLibVLC.setTime(media.getTime());

                mLastAudioTrack = media.getAudioTrack();
                mLastSpuTrack = media.getSpuTrack();
            } else {
                // not in media library
                long rTime = preferences.getLong(PreferencesActivity.VIDEO_RESUME_TIME, -1);
                SharedPreferences.Editor editor = preferences.edit();
                editor.putLong(PreferencesActivity.VIDEO_RESUME_TIME, -1);
                editor.commit();
                if (rTime > 0)
                    mLibVLC.setTime(rTime);

                if (intentPosition > 0)
                    mLibVLC.setTime(intentPosition);
            }

            String subtitleList_serialized = preferences.getString(PreferencesActivity.VIDEO_SUBTITLE_FILES, null);
            ArrayList<String> prefsList = new ArrayList<String>();
            if (subtitleList_serialized != null) {
                ByteArrayInputStream bis = new ByteArrayInputStream(subtitleList_serialized.getBytes());
                try {
                    ObjectInputStream ois = new ObjectInputStream(bis);
                    prefsList = (ArrayList<String>) ois.readObject();
                } catch (ClassNotFoundException e) {
                } catch (StreamCorruptedException e) {
                } catch (IOException e) {
                }
            }
            for (String x : prefsList) {
                if (!mSubtitleSelectedFiles.contains(x))
                    mSubtitleSelectedFiles.add(x);
            }

            try {
                title = URLDecoder.decode(mLocation, "UTF-8");
            } catch (UnsupportedEncodingException e) {
            } catch (IllegalArgumentException e) {
            }
            if (title.startsWith("file:")) {
                title = new File(title).getName();
                int dotIndex = title.lastIndexOf('.');
                if (dotIndex != -1)
                    title = title.substring(0, dotIndex);
            }
        } else if (itemTitle != null) {
            title = itemTitle;
        }
        mTitle.setText(title);
    }

    @SuppressWarnings("deprecation")
    private int getScreenRotation() {
        WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO /* Android 2.2 has getRotation */) {
            try {
                Method m = display.getClass().getDeclaredMethod("getRotation");
                return (Integer) m.invoke(display);
            } catch (Exception e) {
                return Surface.ROTATION_0;
            }
        } else {
            return display.getOrientation();
        }
    }

    @TargetApi(Build.VERSION_CODES.GINGERBREAD)
    private int getScreenOrientation() {
        switch (getScreenRotation()) {
        case Surface.ROTATION_0:
            return ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
        case Surface.ROTATION_90:
            return ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
        case Surface.ROTATION_180:
            // SCREEN_ORIENTATION_REVERSE_PORTRAIT only available since API Level 9+
            return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO
                    ? ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT
                    : ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        case Surface.ROTATION_270:
            // SCREEN_ORIENTATION_REVERSE_LANDSCAPE only available since API Level 9+
            return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO
                    ? ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE
                    : ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        default:
            return 0;
        }
    }

    private void videoScreenshot() {
        /**
         * ????
         */
        if (mLibVLC.videoIsRecording() && mRecording) {
            boolean recordStop = mLibVLC.videoRecordStop();
            mRecording = false;
            mRecord.setBackgroundResource(R.drawable.record_start);
            mRecord.setOnClickListener(mRecordListener);
            Log.d(TAG, "videoRecordStop res is " + recordStop);
        } else {
            Log.d(TAG, "video record is not starting");
        }

    }

}