zoukankan      html  css  js  c++  java
  • 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--");
                } 
  • 相关阅读:
    MySql的常用命令
    yum命令配置及使用说明和常见问题处理
    oracle12c创建用户和表空间出现的问题
    oracle云部署
    ORA-12154: TNS:could not resolve the connect identifier specified
    Linux之iptables
    Linux之MySQL
    Linux之apache
    oracle查锁表
    cookie 和 HttpSession
  • 原文地址:https://www.cnblogs.com/daniulivesdk/p/11362781.html
Copyright © 2011-2022 走看看