基于安卓平台,客户端视频监控的实现(三)

来源:互联网 发布:r语言数据分析实例 编辑:程序博客网 时间:2024/06/05 08:21

关于VideoPlayerActivity,首先看一下xml,大概了解会实现什么功能。界面是如何反馈的,这也是我比较喜欢的查看别人代码的方式,从直观的xml入手。

<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent" >    <SurfaceView        android:id="@+id/main_surface"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_gravity="center" />    <FrameLayout        android:id="@+id/video_player_overlay"        android:layout_width="fill_parent"        android:layout_height="fill_parent" >        <TextView            android:id="@+id/video_player_title"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_gravity="center_horizontal"            android:layout_margin="20dp"            android:textSize="20sp" />        <LinearLayout            android:layout_width="fill_parent"            android:layout_height="wrap_content"            android:layout_gravity="bottom"            android:layout_margin="10dp"            android:orientation="vertical" >            <LinearLayout                android:layout_width="fill_parent"                android:layout_height="wrap_content"                android:orientation="horizontal" >                <TextView                    android:id="@+id/video_player_time"                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:layout_gravity="center_vertical"                    android:layout_marginRight="20dp"                    android:layout_weight="1"                    android:gravity="left"                    android:text="00:00" />                <TextView                    android:id="@+id/video_player_showinfo"                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:layout_gravity="center"                    android:text="@string/video_player_best_fit" />            </LinearLayout>            <RelativeLayout                android:layout_width="fill_parent"                android:layout_height="42dp"                android:layout_gravity="center_horizontal" >                <ImageView                    android:id="@+id/video_player_playpause"                    android:layout_width="wrap_content"                    android:layout_height="85dp"                    android:layout_alignParentTop="true"                    android:layout_centerHorizontal="true"                    android:focusable="true"                    android:src="@drawable/ic_pause_selector" />                <ImageView                    android:id="@+id/video_player_size"                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:layout_alignParentRight="true"                    android:focusable="true"                    android:src="@drawable/ic_size_selector" />            </RelativeLayout>        </LinearLayout>        <Button            android:id="@+id/snapShot"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_margin="10dp"            android:text="截图" />        <Button            android:id="@+id/videoRecord"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_gravity="right"            android:layout_margin="10dp"            android:text="录像" />    </FrameLayout></FrameLayout>

在Activity,onCreate初始化的时候,先设置surfaceView的尺寸大小

getWindow().getDecorView().findViewById(android.R.id.content).setOnSystemUiVisibilityChangeListener(                    new OnSystemUiVisibilityChangeListener() {                        @Override                        public void onSystemUiVisibilityChange(int visibility) {                            if (visibility == mUiVisibility)                                return;                            setSurfaceSize(mVideoWidth, mVideoHeight, mSarNum, mSarDen);                            if (visibility == View.SYSTEM_UI_FLAG_VISIBLE) {                                Log.d(TAG, "onSystemUiVisibilityChange");                            }                            mUiVisibility = visibility;                        }                    });   public void setSurfaceSize(int width, int height, int sar_num, int sar_den) {        if (width * height == 0)            return;        mVideoHeight = height;        mVideoWidth = width;        mSarNum = sar_num;        mSarDen = sar_den;        Message msg = mHandler.obtainMessage(SURFACE_SIZE);        mHandler.sendMessage(msg);    }public 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 SURFACE_SIZE:                    activity.changeSurfaceSize();                    break;            }        }    }//surfaceView的回调,其实主要就是调用mLibVLC.attachSurface(holder.getSurface(), VideoPlayerActivity.this); /**     * 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);        }        @Override        public void surfaceCreated(SurfaceHolder holder) {        }        @Override        public void surfaceDestroyed(SurfaceHolder holder) {            mLibVLC.detachSurface();        }    };

根据xml可以看出页面提供如下功能:

 @Override    public void onClick(View v) {        switch (v.getId()) {            case R.id.video_player_playpause://开始暂停                if (mLibVLC.isPlaying()) {                    mLibVLC.pause();                    btnPlayPause.setImageResource(R.drawable.ic_play_selector);                } else {                    mLibVLC.play();                    btnPlayPause.setImageResource(R.drawable.ic_pause_selector);                }                break;            case R.id.video_player_size://改变窗口的大小                if (mCurrentSize < SURFACE_ORIGINAL) {                    mCurrentSize++;                } else {                    mCurrentSize = 0;                }                changeSurfaceSize();                break;            case R.id.snapShot://截图                snapShot();                break;            case R.id.videoRecord://录像                videoRecord();                break;        }    }

关于截图和录像,lib方法已经封装好了,只需要调用,写文件就可以。

    /**     * 截图     */    private void snapShot() {        try {            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");            String name = df.format(new Date());            name = BitmapUtils.getSDPath() + "/zhaozhe/capture/" + name + ".png";            File file = new File(name);            if (!file.exists())                file.createNewFile();            if (mLibVLC.takeSnapShot(name, 640, 360)) {                mToastUtil.makeText(getApplicationContext(), "已保存", Toast.LENGTH_LONG);            } else {                mToastUtil.makeText(getApplicationContext(), "截图失败", Toast.LENGTH_LONG);            }        } catch (Exception e) {            e.printStackTrace();        }    }    /**     * 录像和停止录像     */    private void videoRecord() {        try {            if (mLibVLC.videoIsRecording()) {                if (mLibVLC.videoRecordStop()) {                    mToastUtil.makeText(getApplicationContext(), "停止录像", Toast.LENGTH_LONG);                } else {                    mToastUtil.makeText(getApplicationContext(), "停止录像失败", Toast.LENGTH_LONG);                }            } else {                SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");                String name = df.format(new Date());                if (mLibVLC.videoRecordStart(BitmapUtils.getSDPath() + "/zhaozhe/video/" + name)) {                    mToastUtil.makeText(getApplicationContext(), "开始录像", Toast.LENGTH_LONG);                } else {                    mToastUtil.makeText(getApplicationContext(), "开始录像失败", Toast.LENGTH_LONG);                }            }        } catch (Exception e) {            e.printStackTrace();        }    }

改变窗体大小:

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;        }        if (dw * dh == 0)            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;        // // calculate aspect ratio        // double ar = (double) mVideoWidth / (double) mVideoHeight;        // // calculate display aspect ratio        // double dar = (double) dw / (double) dh;        switch (mCurrentSize) {            case SURFACE_BEST_FIT:                mTextShowInfo.setText(R.string.video_player_best_fit);                if (dar < ar)                    dh = (int) (dw / ar);                else                    dw = (int) (dh * ar);                break;            case SURFACE_FIT_HORIZONTAL:                mTextShowInfo.setText(R.string.video_player_fit_horizontal);                dh = (int) (dw / ar);                break;            case SURFACE_FIT_VERTICAL:                mTextShowInfo.setText(R.string.video_player_fit_vertical);                dw = (int) (dh * ar);                break;            case SURFACE_FILL:                break;            case SURFACE_16_9:                mTextShowInfo.setText(R.string.video_player_16x9);                ar = 16.0 / 9.0;                if (dar < ar)                    dh = (int) (dw / ar);                else                    dw = (int) (dh * ar);                break;            case SURFACE_4_3:                mTextShowInfo.setText(R.string.video_player_4x3);                ar = 4.0 / 3.0;                if (dar < ar)                    dh = (int) (dw / ar);                else                    dw = (int) (dh * ar);                break;            case SURFACE_ORIGINAL:                mTextShowInfo.setText(R.string.video_player_original);                dh = mVideoHeight;                dw = mVideoWidth;                break;        }        surfaceHolder.setFixedSize(mVideoWidth, mVideoHeight);        LayoutParams lp = surfaceView.getLayoutParams();        lp.width = dw;        lp.height = dh;        surfaceView.setLayoutParams(lp);        surfaceView.invalidate();    }

关于时间轴的显示,主要是一个handler循环发消息:

private Handler handler = new Handler() {        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);            int time = (int) mLibVLC.getTime();            int length = (int) mLibVLC.getLength();            showVideoTime(time, length);            Log.d(TAG, "handle time = " + time + ", length = " + length);            handler.sendEmptyMessageDelayed(0, 1000);        }    };    private void showVideoTime(int t, int l) {        mTextTime.setText(millisToString(t));    } private Handler handler = new Handler() {        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);            int time = (int) mLibVLC.getTime();            int length = (int) mLibVLC.getLength();            showVideoTime(time, length);            Log.d(TAG, "handle time = " + time + ", length = " + length);            handler.sendEmptyMessageDelayed(0, 1000);        }    };

关于Vlc Android,就那么多,但是仍然感觉了解的是皮毛,实际在项目调试的过程中仍然会遇到一些问题,持续记录中,希望和大家多多交流。菜鸟一枚,不喜勿喷。

阅读全文
0 0
原创粉丝点击