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多点触控技术,实现对图片的放大缩小平移,惯性滑动等功能