Android播放器实现视频窗口实时放大缩小功能

Posted daniulivesdk

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android播放器实现视频窗口实时放大缩小功能相关的知识,希望对你有一定的参考价值。

很多开发者希望android播放端实现视频窗口的放大缩小功能,为此,我们做了个简单的demo,通过播放端回调RGB数据,直接在上层view操作处理即可,Github:https://github.com/daniulive/SmarterStreaming

无视频无真相:http://www.iqiyi.com/w_19s9sa7epp.html

基本流程如下:

1. 基础的初始化和参数设定

        libPlayer = new SmartPlayerJniV2();
        myContext = this.getApplicationContext();
        sSurfaceView = (SurfaceView) this.findViewById(R.id.surface);
        surface_renderer = new RGBSurfaceRenderer(sSurfaceView);
技术图片
private void InitAndSetConfig() 
        playerHandle = libPlayer.SmartPlayerOpen(myContext);

        if (playerHandle == 0) 
            Log.e(TAG, "surfaceHandle with nil..");
            return;
        

        libPlayer.SetSmartPlayerEventCallbackV2(playerHandle,
                new EventHandeV2());

        libPlayer.SmartPlayerSetBuffer(playerHandle, playBuffer);

        // set report download speed(默认2秒一次回调 用户可自行调整report间隔)
        libPlayer.SmartPlayerSetReportDownloadSpeed(playerHandle, 1, 2);

        libPlayer.SmartPlayerSetFastStartup(playerHandle, isFastStartup ? 1 : 0);

        //设置RTSP超时时间
        int rtsp_timeout = 10;
        libPlayer.SmartPlayerSetRTSPTimeout(playerHandle, rtsp_timeout);

        //设置RTSP TCP/UDP模式自动切换
        int is_auto_switch_tcp_udp = 1;
        libPlayer.SmartPlayerSetRTSPAutoSwitchTcpUdp(playerHandle, is_auto_switch_tcp_udp);

        libPlayer.SmartPlayerSaveImageFlag(playerHandle, 1);

        // It only used when playback RTSP stream..
        // libPlayer.SmartPlayerSetRTSPTcpMode(playerHandle, 1);

        playbackUrl = "rtmp://202.69.69.180:443/webcast/bshdlive-pc";

        //playbackUrl = "rtsp://184.72.239.149/vod/mp4://BigBuckBunny_175k.mov";

        libPlayer.SmartPlayerSetUrl(playerHandle, playbackUrl);
    
技术图片

2.  设置External Render,回调RGBA数据

libPlayer.SmartPlayerSetExternalRender(playerHandle, new RGBAExternalRender());

Log.i(TAG, "Start playback stream++");

                InitAndSetConfig();

                // External Render
                libPlayer.SmartPlayerSetExternalRender(playerHandle, new RGBAExternalRender());

                libPlayer.SmartPlayerSetAudioOutputType(playerHandle, 0);

                if (isMute) 
                    libPlayer.SmartPlayerSetMute(playerHandle, isMute ? 1
                            : 0);
                

                if (isHardwareDecoder) 
                    int isSupportHevcHwDecoder = libPlayer.SetSmartPlayerVideoHevcHWDecoder(playerHandle, 1);

                    int isSupportH264HwDecoder = libPlayer
                            .SetSmartPlayerVideoHWDecoder(playerHandle, 1);

                    Log.i(TAG, "isSupportH264HwDecoder: " + isSupportH264HwDecoder + ", isSupportHevcHwDecoder: " + isSupportHevcHwDecoder);
                

                libPlayer.SmartPlayerSetLowLatencyMode(playerHandle, isLowLatency ? 1
                        : 0);

                libPlayer.SmartPlayerSetFlipVertical(playerHandle, is_flip_vertical ? 1 : 0);

                libPlayer.SmartPlayerSetFlipHorizontal(playerHandle, is_flip_horizontal ? 1 : 0);

                libPlayer.SmartPlayerSetRotation(playerHandle, rotate_degrees);

                int iPlaybackRet = libPlayer
                        .SmartPlayerStartPlay(playerHandle);

                if (iPlaybackRet != 0) 
                    Log.e(TAG, "Call SmartPlayerStartPlay failed..");
                    return;
                

                surface_renderer.StartRender();

                btnStartStopPlayback.setText("停止播放 ");

                isPlaying = true;
                Log.i(TAG, "Start playback stream--");
技术图片

3. 回调RGBA数据:

   class RGBAExternalRender implements NTExternalRender 
        // public static final int NT_FRAME_FORMAT_RGBA = 1;
        // public static final int NT_FRAME_FORMAT_ABGR = 2;
        // public static final int NT_FRAME_FORMAT_I420 = 3;

        private int width_ = 0;
        private int height_ = 0;
        private int row_bytes_ = 0;
        private ByteBuffer rgba_buffer_ = null;

        @Override
        public int getNTFrameFormat() 
            Log.i(TAG, "RGBAExternalRender::getNTFrameFormat return "
                    + NT_FRAME_FORMAT_RGBA);
            return NT_FRAME_FORMAT_RGBA;
        

        @Override
        public void onNTFrameSizeChanged(int width, int height) 
            width_ = width;
            height_ = height;

            row_bytes_ = width_ * 4;

            Log.i(TAG, "RGBAExternalRender::onNTFrameSizeChanged width_:"
                    + width_ + " height_:" + height_);

            rgba_buffer_ = ByteBuffer.allocateDirect(row_bytes_ * height_);
        

        @Override
        public ByteBuffer getNTPlaneByteBuffer(int index) 
            if (index == 0) 
                return rgba_buffer_;
             else 
                Log.e(TAG,
                        "RGBAExternalRender::getNTPlaneByteBuffer index error:"
                                + index);
                return null;
            
        

        @Override
        public int getNTPlanePerRowBytes(int index) 
            if (index == 0) 
                return row_bytes_;
             else 
                Log.e(TAG,
                        "RGBAExternalRender::getNTPlanePerRowBytes index error:"
                                + index);
                return 0;
            
        

        public void onNTRenderFrame(int width, int height, long timestamp) 
            if (rgba_buffer_ == null)
                return;

           // rgba_buffer_.rewind();

            // copy buffer

            // test
            // byte[] test_buffer = new byte[16];
            // rgba_buffer_.get(test_buffer);

            //Log.i(TAG, "RGBAExternalRender:onNTRenderFrame w=" + width + " h="
            //        + height + " timestamp=" + timestamp);

            // Log.i(TAG, "RGBAExternalRender:onNTRenderFrame rgba:" +
            // bytesToHexString(test_buffer));

            if ( surface_renderer != null)
            
                surface_renderer.SetRGBImage(width, height, rgba_buffer_);
            
        
    
技术图片

4. 对视频view进行放大缩小等状态处理:

        @SuppressLint("ClickableViewAccessibility")
        public RGBSurfaceRenderer(SurfaceView view)
        
            surface_holder_ = view.getHolder();
            if (surface_holder_ == null)
            
                Log.e(TAG, "RGBSurfaceRenderer, surfaceHolder with null..");
                return;
            
            surface_holder_.addCallback(this);

            view.setOnTouchListener(new View.OnTouchListener()
            
                @Override
                public boolean onTouch(View v, MotionEvent event)
                
                    Log.e(TAG, "onTouch called..");
                    switch (event.getAction() & MotionEvent.ACTION_MASK) 
                        case MotionEvent.ACTION_DOWN:
                            start_point_.set(event.getX(), event.getY());
                            status_ = DRAG;
                            break;

                        case MotionEvent.ACTION_POINTER_DOWN:
                            float distance = spacing(event);
                            if (distance > 10f) 

                                status_ = ZOOM;
                                start_distance_ = distance;
                            
                            break;

                        case MotionEvent.ACTION_MOVE:
                            if (status_ == DRAG) 
                                dragAction(event);
                             else 

                                if (event.getPointerCount() == 1)
                                    return true;
                                zoomAcition(event);
                            
                            break;
                        case MotionEvent.ACTION_UP:
                        case MotionEvent.ACTION_POINTER_UP:
                            status_ = NONE;
                            break;
                        default:
                            break;
                    

                    return true;
                
            );

        
技术图片

5. 关闭播放:

if (isPlaying) 
                Log.i(TAG, "Stop playback stream++");

                int iRet = libPlayer.SmartPlayerStopPlay(playerHandle);

                if (iRet != 0) 
                    Log.e(TAG, "Call SmartPlayerStopPlay failed..");
                    return;
                

                surface_renderer.StopRender();

                libPlayer.SmartPlayerClose(playerHandle);
                playerHandle = 0;

                isPlaying = false;
                btnStartStopPlayback.setText("开始播放 ");

                Log.i(TAG, "Stop playback stream--");
             
技术图片

以上是关于Android播放器实现视频窗口实时放大缩小功能的主要内容,如果未能解决你的问题,请参考以下文章

Android多点触控技术,实现对图片的放大缩小平移,惯性滑动等功能

旋转,拖动,放大,缩小Android中的视频和图像

crt屏幕缩小放大

android如何对viewpager里面的图片进行缩放

Android------实现图片双击放大,缩小,左右滑动的多种方式

FPGA视频拼接器的放大和缩小功能