android媒体播放框架,Android 使用超简单的多媒体播放器JiaoZiVideoPlayer

在之前的项目中用到了视频播放的功能,在网上看了看使用了大家用的比较多的一个开源项目JiaoZiVideo可以迅速的实现视频播放的相关功能。

JiaoZiVideo的简单使用

集成了JiaoZiVideo后仅需这几行代码就可以实现播放视频

JZVideoPlayerStandard jzVideoPlayerStandard = (JZVideoPlayerStandard) findViewById(R.id.jz_vedio);

//设置播放视频链接和视频标题

jzVideoPlayerStandard.setUp(VEDIO_URL

, JZVideoPlayer.SCREEN_WINDOW_NORMAL, "饺子在哪里");

//为播放视频设置封面图

jzVideoPlayerStandard.thumbImageView.setImageResource(R.mipmap.ic_launcher);

Jz播放器的简单使用,只需要在布局文件中引入该文件,然后为其设置待播放视频的链接和播放视频的封面图即可。其它的播放相关的无需我们关心。

代码结构分析

aafe648741b6

image.png

JiaoZiVideo主要特点

可以完全自定义UI和任何功能

可以完全自定义UI和任何功能

一行代码切换播放引擎,支持的视频格式和协议取决于播放引擎,android.media.MediaPlayer ijkplayer

完美检测列表滑动

可实现全屏播放,小窗播放

能在ListView、ViewPager和ListView、ViewPager和Fragment等多重嵌套模式下全屏工作

可以在加载、暂停、播放等各种状态中正常进入全屏和退出全屏

多种视频适配屏幕的方式,可铺满全屏,可以全屏剪裁

重力感应自动进入全屏

全屏后手势修改进度和音量

Home键退出界面暂停播放,返回界面继续播放

JiaoZiVideo的使用指南

1..添加类库

implementation 'cn.jzvd:jiaozivideoplayer:7.0.3'

2.添加布局

android:layout_width="match_parent"

android:layout_height="200dp">

android:id="@+id/jz_video"

android:layout_width="match_parent"

android:layout_height="200dp" />

3.设置视频地址、缩略图地址、标题

MyJzvdStd jzvdStd = (MyJzvdStd) findViewById(R.id.jz_video);

jzvdStd.setUp("http://jzvd.nathen.cn/c6e3dc12a1154626b3476d9bf3bd7266/6b56c5f0dc31428083757a45764763b0-5287d2089db37e62345123a1be272f8b.mp4"

, "饺子闭眼睛");

jzvdStd.thumbImageView.setImage("http://p.qpic.cn/videoyun/0/2449_43b6f696980311e59ed467f22794e792_1/640");

4.在Activity中

@Override

public void onBackPressed() {

if (Jzvd.backPress()) {

return;

}

super.onBackPressed();

}

@Override

protected void onPause() {

super.onPause();

Jzvd.releaseAllVideos();

}

5.在AndroidManifest.xml中

android:name=".MainActivity"

android:configChanges="orientation|screenSize|keyboardHidden"

android:screenOrientation="portrait" />

以上只是简单的播放视频功能,但是大家的项目需求里应该不仅仅只是需要播放视频就好了,所以下面写一下还有哪些常规使用方法

math?formula=%5Ccolor%7Brgb(0%2C191%2C255)%7D%7B%E5%8A%A0%E7%BC%A9%E7%95%A5%E8%BD%BD%E5%9B%BE%7D

Glide.with(this).load(Url).into(myJzvdStd.thumbImageView); //推荐使用Glide

math?formula=%5Ccolor%7Brgb(0%2C191%2C255)%7D%7B%E8%87%AA%E5%8A%A8%E6%92%AD%E6%94%BE%7D

自动播放有两种 这里随便选择添加一个,

1. myJzvdStd.startButton.performClick();

2. myJzvdStd.startVideo();

math?formula=%5Ccolor%7Brgb(0%2C191%2C255)%7D%7B%E8%B7%B3%E8%BD%AC%E5%88%B6%E5%AE%9A%E4%BD%8D%E7%BD%AE%E6%92%AD%E6%94%BE%7D

//这里只有开始播放时才生效

mJzvdStd.seekToInAdvance = 20000;

//跳转制定位置播放

JZMediaManager.seekTo(30000);

2.播放sd卡下视频

public void cpAssertVideoToLocalPath() {

try {

InputStream myInput;

OutputStream myOutput = new FileOutputStream(Environment.getExternalStorageDirectory().getAbsolutePath() + "/DCIM/Camera/local_video.mp4");

myInput = this.getAssets().open("local_video.mp4");

byte[] buffer = new byte[1024];

int length = myInput.read(buffer);

while (length > 0) {

myOutput.write(buffer, 0, length);

length = myInput.read(buffer);

}

myOutput.flush();

myInput.close();

myOutput.close();

} catch (IOException e) {

e.printStackTrace();

}

}

myJzvdStd.setUp(Environment.getExternalStorageDirectory().getAbsolutePath() + "/DCIM/Camera/local_video.mp4", "饺子不信",Jzvd.SCREEN_WINDOW_NORMAL, );

这里很多人问为什么播不了,请认真怒url,播不了就是url没怒对

math?formula=%5Ccolor%7Brgb(0%2C191%2C255)%7D%7B%20%E6%92%AD%E6%94%BEassets%E7%9B%AE%E5%BD%95%E4%B8%8B%E7%9A%84%E8%A7%86%E9%A2%91%7D

复制Demo中CustomMediaPlayerAssertFolder类到你的项目下

----------------------------------------------------------------------------

JZDataSource jzDataSource = null;

try {

jzDataSource = new JZDataSource(getAssets().openFd("local_video.mp4"));

jzDataSource.title = "饺子快长大";

} catch (IOException e) {

e.printStackTrace();

}

jzvdStd.setUp(jzDataSource, JzvdStd.SCREEN_WINDOW_NORMAL);

Glide.with(this)

.load("http://jzvd-pic.nathen.cn/jzvd-pic/1bb2ebbe-140d-4e2e-abd2-9e7e564f71ac.png")

.into(jzvdStd.thumbImageView);

Jzvd.setMediaInterface(new CustomMediaPlayerAssertFolder());//进入此页面修改MediaInterface,让此页面的jzvd正常工作

math?formula=%5Ccolor%7Brgb(0%2C191%2C255)%7D%7B%20%E7%9B%B4%E6%8E%A5%E5%85%A8%E5%B1%8F%E6%92%AD%E6%94%BE%7D

JzvdStd.startFullscreen(this, JzvdStd.class, VideoConstant.videoUrlList[6], "饺子辛苦了");

math?formula=%5Ccolor%7Brgb(0%2C191%2C255)%7D%7B%20%E5%BC%80%E5%90%AF%E5%B0%8F%E7%AA%97%E6%92%AD%E6%94%BE%7D

mJzvdStd.startWindowTiny();

math?formula=%5Ccolor%7Brgb(0%2C191%2C255)%7D%7B%20%E5%88%97%E8%A1%A8Item%E5%88%92%E5%87%BA%E5%BC%80%E5%90%AF%E5%B0%8F%E7%AA%97%E6%92%AD%E6%94%BE%20%7D

1.Listview

listView.setOnScrollListener(new AbsListView.OnScrollListener() {

@Override

public void onScrollStateChanged(AbsListView view, int scrollState) {

}

@Override

public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

Jzvd.onScrollAutoTiny(view, firstVisibleItem, visibleItemCount, totalItemCount);

// Jzvd.onScrollReleaseAllVideos(view, firstVisibleItem, visibleItemCount, totalItemCount); 这是不开启列表划出小窗 同时也是画出屏幕释放JZ 划出暂停

}

});

2. RecyclerView 划出列表开启小窗

recyclerView.addOnChildAttachStateChangeListener(new RecyclerView.OnChildAttachStateChangeListener() {

@Override

public void onChildViewAttachedToWindow(View view) {

Jzvd.onChildViewAttachedToWindow(view, R.id.videoplayer);

}

@Override

public void onChildViewDetachedFromWindow(View view) {

Jzvd.onChildViewDetachedFromWindow(view);

}

});

2.1 RecyclerView划出屏幕释放JZ,同时也是不开启列表划出显示小窗

recyclerView.addOnChildAttachStateChangeListener(new RecyclerView.OnChildAttachStateChangeListener() {

@Override

public void onChildViewAttachedToWindow(View view) {

}

@Override

public void onChildViewDetachedFromWindow(View view) {

Jzvd jzvd = view.findViewById(R.id.videoplayer);

if (jzvd != null && jzvd.jzDataSource.containsTheUrl(JZMediaManager.getCurrentUrl())) {

Jzvd currentJzvd = JzvdMgr.getCurrentJzvd();

if (currentJzvd != null && currentJzvd.currentScreen != Jzvd.SCREEN_WINDOW_FULLSCREEN) {

Jzvd.releaseAllVideos();

}

}

}

});

math?formula=%5Ccolor%7Brgb(0%2C191%2C255)%7D%7B%20%E5%B0%8F%E5%B1%8F%E6%92%AD%E6%94%BE%E6%97%A0%E5%A3%B0%E9%9F%B3%EF%BC%8C%E5%85%A8%E5%B1%8F%E6%9C%89%E5%A3%B0%E9%9F%B3%20%7D

创建一个类继承JzvdStd并在XML设置

public class JzvdStdVolumeAfterFullscreen extends JzvdStd {

public JzvdStdVolumeAfterFullscreen(Context context) {

super(context);

}

public JzvdStdVolumeAfterFullscreen(Context context, AttributeSet attrs) {

super(context, attrs);

}

@Override

public void onPrepared() {

super.onPrepared();

if (currentScreen == SCREEN_WINDOW_FULLSCREEN) {

JZMediaManager.instance().jzMediaInterface.setVolume(1f, 1f);

} else {

JZMediaManager.instance().jzMediaInterface.setVolume(0f, 0f);

}

}

/**

* 进入全屏模式的时候关闭静音模式

*/

@Override

public void startWindowFullscreen() {

super.startWindowFullscreen();

JZMediaManager.instance().jzMediaInterface.setVolume(1f, 1f);

}

/**

* 退出全屏模式的时候开启静音模式

*/

@Override

public void playOnThisJzvd() {

super.playOnThisJzvd();

JZMediaManager.instance().jzMediaInterface.setVolume(0f, 0f);

}

}

math?formula=%5Ccolor%7Brgb(0%2C191%2C255)%7D%7B%20%E5%85%A8%E5%B1%8F%E7%8A%B6%E6%80%81%E6%92%AD%E6%94%BE%E5%AE%8C%E6%88%90%EF%BC%8C%E4%B8%8D%E9%80%80%E5%87%BA%E5%85%A8%E5%B1%8F%20%7D

创建一个类继承JzvdStd并在XML设置

public class JzvdStdAutoCompleteAfterFullscreen extends JzvdStd {

public JzvdStdAutoCompleteAfterFullscreen(Context context) {

super(context);

}

public JzvdStdAutoCompleteAfterFullscreen(Context context, AttributeSet attrs) {

super(context, attrs);

}

@Override

public void startVideo() {

if (currentScreen == SCREEN_WINDOW_FULLSCREEN) {

Log.d(TAG, "startVideo [" + this.hashCode() + "] ");

initTextureView();

addTextureView();

AudioManager mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);

mAudioManager.requestAudioFocus(onAudioFocusChangeListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);

JZUtils.scanForActivity(getContext()).getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

JZMediaManager.setDataSource(jzDataSource);

JZMediaManager.instance().positionInList = positionInList;

onStatePreparing();

} else {

super.startVideo();

}

}

@Override

public void onAutoCompletion() {

if (currentScreen == SCREEN_WINDOW_FULLSCREEN) {

onStateAutoComplete();

} else {

super.onAutoCompletion();

}

}

}

math?formula=%5Ccolor%7Brgb(0%2C191%2C255)%7D%7B%20%E5%85%A8%E5%B1%8F%E6%A8%A1%E5%BC%8F%E4%B8%8B%E6%98%BE%E7%A4%BA%E5%88%86%E4%BA%AB%E6%8C%89%E9%92%AE%20%7D

复制DEMO下的layout文件在 layout_top 布局下 添加你的分享按钮

public class JzvdStdShowShareButtonAfterFullscreen extends JzvdStd {

public ImageView shareButton;

public JzvdStdShowShareButtonAfterFullscreen(Context context) {

super(context);

}

public JzvdStdShowShareButtonAfterFullscreen(Context context, AttributeSet attrs) {

super(context, attrs);

}

@Override

public void init(Context context) {

super.init(context);

shareButton = findViewById(R.id.share);

shareButton.setOnClickListener(this);

}

@Override

public int getLayoutId() {

return R.layout.layout_standard_with_share_button;

}

@Override

public void onClick(View v) {

super.onClick(v);

if (v.getId() == R.id.share) {

Toast.makeText(getContext(), "Whatever the icon means", Toast.LENGTH_SHORT).show();

}

}

@Override

public void setUp(JZDataSource jzDataSource, int screen) {

super.setUp(jzDataSource, screen);

if (currentScreen == SCREEN_WINDOW_FULLSCREEN) {

shareButton.setVisibility(View.VISIBLE);

} else {

shareButton.setVisibility(View.INVISIBLE);

}

}

}

math?formula=%5Ccolor%7Brgb(0%2C191%2C255)%7D%7B%20%E5%B0%8F%E5%B1%8F%E7%8A%B6%E6%80%81%E4%B8%8B%E4%B8%8D%E6%98%BE%E7%A4%BA%E6%A0%87%E9%A2%98%EF%BC%8C%E5%85%A8%E5%B1%8F%E6%A8%A1%E5%BC%8F%E4%B8%8B%E6%98%BE%E7%A4%BA%E6%A0%87%E9%A2%98%20%7D

public class JzvdStdShowTitleAfterFullscreen extends JzvdStd {

public JzvdStdShowTitleAfterFullscreen(Context context) {

super(context);

}

public JzvdStdShowTitleAfterFullscreen(Context context, AttributeSet attrs) {

super(context, attrs);

}

@Override

public void setUp(JZDataSource jzDataSource, int screen) {

super.setUp(jzDataSource, screen);

if (currentScreen == SCREEN_WINDOW_FULLSCREEN) {

titleTextView.setVisibility(View.VISIBLE);

} else {

titleTextView.setVisibility(View.INVISIBLE);

}

}

}

math?formula=%5Ccolor%7Brgb(0%2C191%2C255)%7D%7B%20%E6%92%AD%E6%94%BEMP3%20%7D

public class JzvdStdMp3 extends JzvdStd {

public JzvdStdMp3(Context context) {

super(context);

}

public JzvdStdMp3(Context context, AttributeSet attrs) {

super(context, attrs);

}

@Override

public int getLayoutId() {

return R.layout.jz_layout_standard_mp3;

}

@Override

public void onClick(View v) {

if (v.getId() == cn.jzvd.R.id.thumb &&

(currentState == CURRENT_STATE_PLAYING ||

currentState == CURRENT_STATE_PAUSE)) {

onClickUiToggle();

} else if (v.getId() == R.id.fullscreen) {

} else {

super.onClick(v);

}

}

//changeUiTo 真能能修改ui的方法

@Override

public void changeUiToNormal() {

super.changeUiToNormal();

}

@Override

public void changeUiToPreparing() {

super.changeUiToPreparing();

}

@Override

public void changeUiToPlayingShow() {

super.changeUiToPlayingShow();

thumbImageView.setVisibility(View.VISIBLE);

}

@Override

public void changeUiToPlayingClear() {

super.changeUiToPlayingClear();

thumbImageView.setVisibility(View.VISIBLE);

}

@Override

public void changeUiToPauseShow() {

super.changeUiToPauseShow();

thumbImageView.setVisibility(View.VISIBLE);

}

@Override

public void changeUiToPauseClear() {

super.changeUiToPauseClear();

thumbImageView.setVisibility(View.VISIBLE);

}

@Override

public void changeUiToComplete() {

super.changeUiToComplete();

}

@Override

public void changeUiToError() {

super.changeUiToError();

}

}

jzvdStdMp3 = findViewById(R.id.jz_videoplayer_mp3);

jzvdStdMp3.setUp(URL, "饺子摇摆", Jzvd.SCREEN_WINDOW_NORMAL);

Glide.with(this)

.load(VideoConstant.videoThumbs[0][1])

.into(jzvdStdMp3.thumbImageView);

math?formula=%5Ccolor%7Brgb(0%2C191%2C255)%7D%7B%20%E6%92%AD%E6%94%BE%E5%AE%8C%E6%88%90%E4%B8%8D%E6%98%BE%E7%A4%BA%E9%A2%84%E8%A7%88%E5%9B%BE%20%7D

public class JzvdStdShowTextureViewAfterAutoComplete extends JzvdStd {

public JzvdStdShowTextureViewAfterAutoComplete(Context context) {

super(context);

}

public JzvdStdShowTextureViewAfterAutoComplete(Context context, AttributeSet attrs) {

super(context, attrs);

}

@Override

public void onAutoCompletion() {

super.onAutoCompletion();

thumbImageView.setVisibility(View.GONE);

}

}

math?formula=%5Ccolor%7Brgb(0%2C191%2C255)%7D%7B%20Home%E9%94%AE%E9%80%80%E5%87%BA%E7%95%8C%E9%9D%A2%E6%9A%82%E5%81%9C%E6%92%AD%E6%94%BE%EF%BC%8C%E8%BF%94%E5%9B%9E%E7%95%8C%E9%9D%A2%E7%BB%A7%E7%BB%AD%E6%92%AD%E6%94%BE%20%7D

@Override

protected void onResume() {

super.onResume();

//home back

JzvdStd.goOnPlayOnResume();

}

@Override

protected void onPause() {

super.onPause();

// Jzvd.clearSavedProgress(this, null);

//home back

JzvdStd.goOnPlayOnPause();

}

math?formula=%5Ccolor%7Brgb(0%2C191%2C255)%7D%7B%20%E8%BE%B9%E6%92%AD%E8%BE%B9%E7%BC%93%E5%AD%98%E5%92%8C%E6%B8%85%E6%99%B0%E5%BA%A6%E5%88%87%E6%8D%A2%20%7D

1. 集成videocache implementation 'com.danikula:videocache:2.7.0',并初始化

public class ApplicationDemo extends Application {

@Override

public void onCreate() {

super.onCreate();

// LeakCanary.install(this);

}

private HttpProxyCacheServer proxy;

public static HttpProxyCacheServer getProxy(Context context) {

ApplicationDemo app = (ApplicationDemo) context.getApplicationContext();

return app.proxy == null ? (app.proxy = app.newProxy()) : app.proxy;

}

private HttpProxyCacheServer newProxy() {

return new HttpProxyCacheServer(this);

}

}

2.引用

LinkedHashMap map = new LinkedHashMap();

String proxyUrl = ApplicationDemo.getProxy(this).getProxyUrl(VideoConstant.videoUrls[0][9]);

map.put("高清", proxyUrl);

map.put("标清", VideoConstant.videoUrls[0][6]);

map.put("普清", VideoConstant.videoUrlList[0]);

JZDataSource jzDataSource = new JZDataSource(map, "饺子不信");

jzDataSource.looping = true;

jzDataSource.currentUrlIndex = 2;

jzDataSource.headerMap.put("key", "value");//header

mJzvdStd.setUp(jzDataSource

, JzvdStd.SCREEN_WINDOW_NORMAL);

Glide.with(this).load(VideoConstant.videoThumbList[0]).into(mJzvdStd.thumbImageView);

math?formula=%5Ccolor%7Brgb(0%2C191%2C255)%7D%7B%E9%87%8D%E5%A4%8D%E6%92%AD%E6%94%BE%7D

创建一个类集成JzvdStd并在XML设置

public class JZVideoPlayerStandardLoopVideo extends JzvdStd{

public JZVideoPlayerStandardLoopVideo (Context context) {

super(context);

}

public JZVideoPlayerStandardLoopVideo (Context context, AttributeSet attrs) {

super(context, attrs);

}

@Override

public void onAutoCompletion() {

super.onAutoCompletion();

startVideo();

}

}

还有一种方法就是上面清晰度切换loop循环标志

math?formula=%5Ccolor%7Brgb(0%2C191%2C255)%7D%7B%E9%87%8D%E5%8A%9B%E6%84%9F%E5%BA%94%E8%87%AA%E5%8A%A8%E8%BF%9B%E5%85%A5%E5%85%A8%E5%B1%8F%7D

SensorManager mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);

Jzvd.JZAutoFullscreenListener mSensorEventListener = new Jzvd.JZAutoFullscreenListener();

@Override

protected void onResume() {

super.onResume();

Sensor accelerometerSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

mSensorManager.registerListener(mSensorEventListener, accelerometerSensor, SensorManager.SENSOR_DELAY_NORMAL);

}

@Override

protected void onPause() {

super.onPause();

mSensorManager.unregisterListener(mSensorEventListener);

}

math?formula=%5Ccolor%7Brgb(0%2C191%2C255)%7D%7B%E9%87%8D%E5%8A%9B%E6%84%9F%E5%BA%94%7D

Jzvd.FULLSCREEN_ORIENTATION=ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;

Jzvd.NORMAL_ORIENTATION = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;

两个变量控制全屏前后的屏幕方向

math?formula=%5Ccolor%7Brgb(0%2C191%2C255)%7D%7B%20%E4%B8%8D%E4%BF%9D%E5%AD%98%E6%92%AD%E6%94%BE%E8%BF%9B%E5%BA%A6%7D

Jzvd.SAVE_PROGRESS = false;

math?formula=%5Ccolor%7Brgb(0%2C191%2C255)%7D%7B%20%E5%8F%96%E6%B6%88%E6%92%AD%E6%94%BE%E6%97%B6%E5%9C%A8%E9%9D%9EWIFIDialog%E6%8F%90%E7%A4%BA%7D

Jzvd.WIFI_TIP_DIALOG_SHOWED=true;

math?formula=%5Ccolor%7Brgb(0%2C191%2C255)%7D%7B%E6%B8%85%E9%99%A4%E6%9F%90%E4%B8%AAURL%E8%BF%9B%E5%BA%A6%7D

Jzvd.clearSavedProgress(this, "url");

math?formula=%5Ccolor%7Brgb(0%2C191%2C255)%7D%7B%E5%88%87%E6%8D%A2%E6%92%AD%E6%94%BE%E5%86%85%E6%A0%B8%20%7D

ijk

复制Demo中JZMediaIjkplayer类到你的项目下

implementation 'tv.danmaku.ijk.media:ijkplayer-java:0.8.4'

implementation 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.4'

Jzvd.setMediaInterface(new JZMediaIjkplayer()); // ijkMediaPlayer

Mediaplayer

Jzvd.setMediaInterface(new JZMediaSystem()); //

exo

复制Demo中JZExoPlayer类到你的项目下

implementation 'com.google.android.exoplayer:exoplayer:2.7.1'

Jzvd.setMediaInterface(new JZExoPlayer()); //exo

math?formula=%5Ccolor%7Brgb(0%2C191%2C255)%7D%7B%E7%94%A8%E6%88%B7%E5%9F%8B%E7%82%B9%E7%BB%9F%E8%AE%A1%7D

Jzvd.setJzUserAction(new MyUserActionStd());

/**

* 这只是给埋点统计用户数据用的,不能写和播放相关的逻辑,监听事件请参考MyJzvdStd,复写函数取得相应事件

*/

class MyUserActionStd implements JZUserActionStd {

@Override

public void onEvent(int type, Object url, int screen, Object... objects) {

switch (type) {

case JZUserAction.ON_CLICK_START_ICON:

Log.i("USER_EVENT", "ON_CLICK_START_ICON" + " title is : " + (objects.length == 0 ? "" : objects[0]) + " url is : " + url + " screen is : " + screen);

break;

case JZUserAction.ON_CLICK_START_ERROR:

Log.i("USER_EVENT", "ON_CLICK_START_ERROR" + " title is : " + (objects.length == 0 ? "" : objects[0]) + " url is : " + url + " screen is : " + screen);

break;

case JZUserAction.ON_CLICK_START_AUTO_COMPLETE:

Log.i("USER_EVENT", "ON_CLICK_START_AUTO_COMPLETE" + " title is : " + (objects.length == 0 ? "" : objects[0]) + " url is : " + url + " screen is : " + screen);

break;

case JZUserAction.ON_CLICK_PAUSE:

Log.i("USER_EVENT", "ON_CLICK_PAUSE" + " title is : " + (objects.length == 0 ? "" : objects[0]) + " url is : " + url + " screen is : " + screen);

break;

case JZUserAction.ON_CLICK_RESUME:

Log.i("USER_EVENT", "ON_CLICK_RESUME" + " title is : " + (objects.length == 0 ? "" : objects[0]) + " url is : " + url + " screen is : " + screen);

break;

case JZUserAction.ON_SEEK_POSITION:

Log.i("USER_EVENT", "ON_SEEK_POSITION" + " title is : " + (objects.length == 0 ? "" : objects[0]) + " url is : " + url + " screen is : " + screen);

break;

case JZUserAction.ON_AUTO_COMPLETE:

Log.i("USER_EVENT", "ON_AUTO_COMPLETE" + " title is : " + (objects.length == 0 ? "" : objects[0]) + " url is : " + url + " screen is : " + screen);

break;

case JZUserAction.ON_ENTER_FULLSCREEN:

Log.i("USER_EVENT", "ON_ENTER_FULLSCREEN" + " title is : " + (objects.length == 0 ? "" : objects[0]) + " url is : " + url + " screen is : " + screen);

break;

case JZUserAction.ON_QUIT_FULLSCREEN:

Log.i("USER_EVENT", "ON_QUIT_FULLSCREEN" + " title is : " + (objects.length == 0 ? "" : objects[0]) + " url is : " + url + " screen is : " + screen);

break;

case JZUserAction.ON_ENTER_TINYSCREEN:

Log.i("USER_EVENT", "ON_ENTER_TINYSCREEN" + " title is : " + (objects.length == 0 ? "" : objects[0]) + " url is : " + url + " screen is : " + screen);

break;

case JZUserAction.ON_QUIT_TINYSCREEN:

Log.i("USER_EVENT", "ON_QUIT_TINYSCREEN" + " title is : " + (objects.length == 0 ? "" : objects[0]) + " url is : " + url + " screen is : " + screen);

break;

case JZUserAction.ON_TOUCH_SCREEN_SEEK_VOLUME:

Log.i("USER_EVENT", "ON_TOUCH_SCREEN_SEEK_VOLUME" + " title is : " + (objects.length == 0 ? "" : objects[0]) + " url is : " + url + " screen is : " + screen);

break;

case JZUserAction.ON_TOUCH_SCREEN_SEEK_POSITION:

Log.i("USER_EVENT", "ON_TOUCH_SCREEN_SEEK_POSITION" + " title is : " + (objects.length == 0 ? "" : objects[0]) + " url is : " + url + " screen is : " + screen);

break;

case JZUserActionStd.ON_CLICK_START_THUMB:

Log.i("USER_EVENT", "ON_CLICK_START_THUMB" + " title is : " + (objects.length == 0 ? "" : objects[0]) + " url is : " + url + " screen is : " + screen);

break;

case JZUserActionStd.ON_CLICK_BLANK:

Log.i("USER_EVENT", "ON_CLICK_BLANK" + " title is : " + (objects.length == 0 ? "" : objects[0]) + " url is : " + url + " screen is : " + screen);

break;

default:

Log.i("USER_EVENT", "unknow");

break;

}

}

}

相关函数回调,屏幕状态,播放器状态,事件

在继承JzvdStd之后,可以通过父类的mCurrentState,取得当前的播放状态。

CURRENT_STATE_IDLE 未知状态,指控件被new出来之后什么都没做

CURRENT_STATE_NORMAL 普通状态

CURRENT_STATE_PREPARING 视频准备状态

CURRENT_STATE_PREPARING_CHANGING_URL 播放中切换url的准备状态

CURRENT_STATE_PLAYING 播放中状态

CURRENT_STATE_PAUSE 暂停状态

CURRENT_STATE_AUTO_COMPLETE 自动播放完成状态

CURRENT_STATE_ERROR 错误状态

复写进入播放状态的函数,取得播放状态的回调

onStateNormal 进入普通状态,通常指setUp之后

onStatePreparing 进入准备中状态,就是loading状态

onStatePlaying 进入播放状态

onStatePause 进入暂停状态

onStateError 进入错误状态

onStateAutoComplete 进入自动播放完成状态

全屏、小窗、非全屏分别是不同的实例,在继承JzvdStd后,通过mCurrentScreen变量,取得当前屏幕类型

SCREEN_WINDOW_NORMAL 普通窗口(进入全屏之前的)

SCREEN_WINDOW_LIST 列表窗口(进入全屏之前)

SCREEN_WINDOW_FULLSCREEN 全屏

SCREEN_WINDOW_TINY 小窗

事件

复写onProgress函数,取得每次播放器设置底部seekBar的进度回调

调用changeUrl函数,切换url

复写onClick函数,取得各种按钮的点击事件

复写onTouch函数,取得全屏之后的手势操作

JiaoZiVideoPlayer的功能远不止上述这些,最近我也在深入的研究中,下篇文章会收集一些大家经常遇到的问题写出来帮助大家,大家有什么建议或者问题可以再下方留言。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/366679.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

送福利:ROKID 语音开发板免费送,开启你的物联网之旅

都让一让,我说个事情:掘金联合 Rokid 开发者社区给大家发福利啦! 掘金联合 Rokid 开发者社区为大家准备了一些福利,只要秀出你的 skill 和技术栈,就有可能获得 Rokid 全栈语音智能开发套件。 ? Rokid开箱试用活动 活…

如何使用JavaScript控制台改进工作流程

作为Web开发人员,很有必要了解如何调试代码。后台开发我们经常使用外部库来记录日志,并在某些情况下格式化显示日志,前端我们会使用断点和控制台,但是我们浏览器的控制台比我们想象的要强大得多。 当我们考虑控制台时&#xff0c…

select、poll、epoll之间的区别总结[整理]

原文:https://www.cnblogs.com/Anker/p/3265058.html 好文章收藏下,慢慢品味 select,poll,epoll都是IO多路复用的机制。I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者…

JPA(七):映射关联关系------映射双向多对一的关联关系

映射双向多对一的关联关系 修改Customer.java package com.dx.jpa.singlemanytoone;import java.util.Date; import java.util.HashSet; import java.util.Set;import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; impo…

如何优雅的绘制一棵省市区三级可选择的树?

开始 总结一下 开发过程中的思路想法 各位大佬们看看就好 首先你拥有的数据结构 所有省市区的信息列表 以及已经选中的信息 用的是element-ui的 el-tree const cityStorage {provinceList:[{id: 1, provinceId: "110000", name: "北京市"}],//所有省ci…

html click事件 参数,vue 实现click同时传入事件对象和自定义参数

这篇文章主要介绍了vue 实现click同时传入事件对象和自定义参数,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧仅仅传入自定义参数HTMLdddddJS代码new Vue({el:#app,methods:{tm:function(e){console.log(e);}}})仅仅传入事件对象HTML…

Android学习(七)—— Android布局

Android布局 1、LinearLayout 线性布局,这种布局在平时的开发中用的最多,内部控件只能水平或竖直进行排列,在搭建较复杂的界面时会有点麻烦。 常用属性 android:orientation 控制控件排列方向,属性值为垂直(vertical…

不一样的ZTree,权限树.js插件

每一个有趣的创新,都源于苦逼的生活。在最近的工作中,遇到一个做权限管理筛选的需求。 简单总结需求: 1展示一个组织中的组织结构 2通过点击组织结构中的任意一个节点可以向上向下查询对应的组织结构 如果你不想苦逼的重复劳动,还…

JavaFX 2:如何加载图像

这是有关如何在JavaFX 2应用程序中加载图像的JavaFX教程。 使用ImageView可以轻松完成此操作。 ImageView是一个节点,用于绘制加载有Image类的图像。 因此,您将首先使用Image类加载图像,然后使用ImageView显示它。 我还将在这里演示如何从本地…

记HTML5 a 标签的一个小坑

今天写了段简单的代码&#xff0c;点击<a>标签时却抛出了这个错误&#xff1a;Uncaught TypeError: download is not a function。代码如下&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><…

C#线程 ---- 线程同步详解

线程同步 说明&#xff1a;接上一篇&#xff0c;注意分享线程同步的必要性和线程同步的方法。 测试代码下载&#xff1a;https://github.com/EkeSu/C-Thread-synchronization-C-.git 一、什么是线程同步&#xff1a; 在同一时间只允许一个线程访问资源的情况称为线程同步。 二、…

响应式方案调研及前端开发管理思考

网易首页响应式风格实现技术调研网易首页实现页面&#xff08;字体&#xff09;响应式风格的方式是在不同尺寸的视口中使用不同的容器类&#xff0c;如图 1所示。当视口大于等于1420px时&#xff0c;使用大尺寸容器类 &#xff08;index2017_1200_wrap&#xff0c;width: 1200p…

linux nexus启动_Linux一键部署Nexus 3私服仓库自动化部署脚本

此脚本是Linux一键部署Nexus 3私服仓库自动化脚本&#xff0c;有需要朋友可以参考&#xff0c;脚本内容如下&#xff1a;环境准备&#xff1a;操作系统&#xff1a;CentOS Linux release 7.8.2003软件版本&#xff1a;Docker&#xff1a;docker-ce-19.03.12[rootlocalhost ~]# …

flex.css快速入门,极速布局

什么是flex.css? css3 flex 布局相信很多人已经听说过甚至已经在开发中使用过它&#xff0c;但是我想我们都会有一个共同的经历&#xff0c;面对它的各种版本&#xff0c;各种坑&#xff0c;傻傻的分不清楚&#xff0c;flex.css就是对flex布局的一种封装&#xff0c;通过简洁…

优化Angularjs的$watch方法

Angularjs的$watch相信大家都知道&#xff0c;而且也经常使用&#xff0c;甚至&#xff0c;你还在为它的某些行为感到恼火。比如&#xff0c;一进入页面&#xff0c;它就会调用一次&#xff0c;我明明希望它在我初始化之后&#xff0c;值再次变动才调用。这种行为给我们带来许多…

JavaFX中的塔防(2)

在上一部分中&#xff0c;我们创建了一个简单的编辑器&#xff0c;让我们放置炮塔。 现在&#xff0c;我们将在敌人起源的地方添加一个生成点&#xff0c;并为其定义攻击目标。 首先&#xff0c;我将通过对象层向地图添加更多信息。 这是标准的TMX&#xff0c;因此我们可以在Ti…

12面魔方公式图解法_三阶魔方入门

一、魔方的构造这里只讲常见的普通三阶魔方。三阶魔方一共有26个色块&#xff0c;分三个层&#xff0c;从上到下分别为顶层、中间层、底层。26个色块按位置分为中心块、角色块、棱色块。中心块6个&#xff0c;角色块8个&#xff0c;棱色块12个。中心块为每一个面最中央的色块。…

Linux ls命令详解

ls常见命令参数 ls: -F 给不同的文件添加不同表示,添加帽子 d/ l* s -a: 显示隐藏文件 以.开头的文件 -p: 只给目录添加/ -t: 按照修改时间排序 time --time-stylelong-iso: ls -l --time-stylelong-iso 显示友好长格式时间 -r: 倒着排序 reverse -S: 按照文件…

caffe 人脸关键点检测_人脸检测关键点新增至81个,比Dlib更精准、更贴边

人脸关键点检测是人脸识别和分析领域中的关键一步&#xff0c;它是诸如自动人脸识别、表情分析、三维人脸重建及三维动画等其它人脸相关问题的前提和突破口。虽然人脸的结构是确定的&#xff0c;由眉毛、眼睛、鼻子和嘴等部位组成&#xff0c;近似是一个刚体&#xff0c;但由于…

美团点评云真机平台实践

背景 随着美团点评业务越来越多&#xff0c;研发团队越来越庞大&#xff0c;对测试手机的需求显著增长。这对公司来说是一笔不小的开支&#xff0c;但现有测试手机资源分配不均&#xff0c;利用率也非常有限&#xff0c;导致各个团队开发、测试过程中都很难做到多机型覆盖。怎…