【Android -- 开源库】JZVideo 的基本使用

在这里插入图片描述

一、简介

高度自定义的安卓视频框架 MediaPlayer exoplayer ijkplayer ffmpeg

目前最新的版本是 7.7.0。
GitHub:JZVideo
中文文档:JZVD文档

特点

  • 可以完全自定义UI和任何功能。
  • 很容易切换播放引擎,支持的视频格式和协议取决于播放引擎,android.media.MediaPlayer或者ijkplayer等。
  • 可以检测列表的滑动。
  • 可以嵌入到多个控件中,比如ListView、Fragment,RecyclerView等等,多重嵌套也可以。
  • 可以实现全屏播放和小窗播放。
  • 可以在加载、暂停和播放等状态下切换全屏和退出全屏。
  • 可以进行屏幕适配,铺满全屏或者全屏裁剪。
  • 好像还支持重力感应自动横屏。
  • 全屏后可以用手势修改进度和音量。
  • Home键退出界面暂停播放,返回界面的时候继续播放。

二、框架引入

1. 在 app/build.gradle 中添加如下依赖:

implementation 'cn.jzvd:jiaozivideoplayer:7.7.0'

2. 在清单文件中添加网络权限:

	<!-- 网络 -->
    <uses-permission android:name="android.permission.INTERNET" />

三、播放在线视频

1. 效果图
01.png

2. 使用
1). 布局中添加如下控件

    <cn.jzvd.JzvdStd
        android:id="@+id/jz_video"
        android:layout_width="match_parent"
        android:layout_height="200dp"/>

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

public class MainActivity extends BaseActivity {
    private String videoUrl = "https://v-cdn.zjol.com.cn/280443.mp4";
    @Override
    protected int getLayoutId() {
        return R.layout.activity_main;
    }

    @Override
    protected void init(Bundle savedInstanceState) {
        initView();
    }

    private void initView() {
        JzvdStd videoPlayer = findViewById(R.id.jz_video);
        videoPlayer.setUp(videoUrl,"追龙");
        videoPlayer.posterImageView.setImageResource(R.mipmap.ic_cover);
//        videoPlayer.startVideo();
    }

    @Override
    public void onBackPressed() {
        if (Jzvd.backPress()) {
            return;
        }
        super.onBackPressed();
    }
    @Override
    protected void onPause() {
        super.onPause();
        Jzvd.releaseAllVideos();
    }
}

四、播放本地视频

1. 效果图
在这里插入图片描述
2. 准备本地小视频
在这里插入图片描述

3. JzvdStdAssert.java

/**
 * Created on 2022/3/10 14:51
 *
 * @author Gong Youqiang
 */
public class JzvdStdAssert extends JzvdStd {
    public JzvdStdAssert(Context context) {
        super(context);
    }

    public JzvdStdAssert(Context context, AttributeSet attrs) {
        super(context, attrs);
    }


    @Override
    public void onPrepared() {
        state = STATE_PREPARED;
        if (!preloading) {
            mediaInterface.start();
            preloading = false;
        }
        onStatePlaying();
    }
}

4. 布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/black"
    android:orientation="vertical"
    tools:context=".machine.MachineActivity">

    <com.hjq.bar.TitleBar
        android:id="@+id/title_bar"
        android:layout_width="match_parent"
        android:background="@color/purple_500"
        android:layout_height="?android:attr/actionBarSize"
        app:title="@string/app_video_title"
        app:titleSize="18sp"
        app:titleStyle="bold"
        app:backButton="true"
        app:leftIcon="@mipmap/ic_back"
        app:titleColor="@color/white"/>

    <com.hkt.devicedetection.video.JzvdStdAssert
        android:id="@+id/jz_video"
        android:layout_gravity="center"
        android:layout_width="600dp"
        android:layout_height="260dp"/>


    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <TextView
            android:id="@+id/tv_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="14sp"
            android:textColor="@color/white"
            android:text="@string/app_video_desc"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:layout_marginBottom="120dp"
            android:layout_marginStart="15dp"
            android:layout_marginEnd="15dp"/>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_above="@id/tv_text"
            android:layout_centerHorizontal="true"
            android:layout_alignParentBottom="true"
            android:gravity="center"
            android:layout_marginBottom="30dp"
            android:layout_marginTop="20dp">
            <ImageView
                android:id="@+id/iv_machine_no"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="8dp"
                android:background="@drawable/shape_image_bg"
                android:src="@mipmap/ic_home_error"/>

            <ImageView
                android:id="@+id/iv_machine_ok"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="80dp"
                android:padding="8dp"
                android:background="@drawable/shape_image_bg"
                android:src="@mipmap/ic_home_ok"/>
        </LinearLayout>

    </RelativeLayout>

</LinearLayout>

5. JZMediaSystemAssertFolder.java

/**
 * Created on 2022/3/10 11:39
 *
 * @author Gong Youqiang
 */
public class JZMediaSystemAssertFolder extends JZMediaInterface implements
        MediaPlayer.OnPreparedListener, MediaPlayer.OnCompletionListener,
        MediaPlayer.OnBufferingUpdateListener, MediaPlayer.OnSeekCompleteListener,
        MediaPlayer.OnErrorListener, MediaPlayer.OnInfoListener,
        MediaPlayer.OnVideoSizeChangedListener {

    public MediaPlayer mediaPlayer;

    public JZMediaSystemAssertFolder(Jzvd jzvd) {
        super(jzvd);
    }

    @Override
    public void prepare() {
        release();
        mMediaHandlerThread = new HandlerThread("JZVD");
        mMediaHandlerThread.start();
        mMediaHandler = new Handler(mMediaHandlerThread.getLooper());//主线程还是非主线程,就在这里
        handler = new Handler();

        mMediaHandler.post(() -> {
            try {
                mediaPlayer = new MediaPlayer();
                mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                mediaPlayer.setLooping(jzvd.jzDataSource.looping);
                mediaPlayer.setOnPreparedListener(JZMediaSystemAssertFolder.this);
                mediaPlayer.setOnCompletionListener(JZMediaSystemAssertFolder.this);
                mediaPlayer.setOnBufferingUpdateListener(JZMediaSystemAssertFolder.this);
                mediaPlayer.setScreenOnWhilePlaying(true);
                mediaPlayer.setOnSeekCompleteListener(JZMediaSystemAssertFolder.this);
                mediaPlayer.setOnErrorListener(JZMediaSystemAssertFolder.this);
                mediaPlayer.setOnInfoListener(JZMediaSystemAssertFolder.this);
                mediaPlayer.setOnVideoSizeChangedListener(JZMediaSystemAssertFolder.this);

                //two lines are different
                AssetFileDescriptor assetFileDescriptor = jzvd.getContext().getAssets().openFd(jzvd.jzDataSource.getCurrentUrl().toString());
                mediaPlayer.setDataSource(assetFileDescriptor.getFileDescriptor(), assetFileDescriptor.getStartOffset(), assetFileDescriptor.getLength());

                mediaPlayer.prepareAsync();
                mediaPlayer.setSurface(new Surface(jzvd.textureView.getSurfaceTexture()));
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    @Override
    public void start() {
        mMediaHandler.post(() -> mediaPlayer.start());
    }

    @Override
    public void pause() {
        mMediaHandler.post(() -> mediaPlayer.pause());
    }

    @Override
    public boolean isPlaying() {
        return mediaPlayer.isPlaying();
    }

    @Override
    public void seekTo(long time) {
        mMediaHandler.post(() -> {
            try {
                mediaPlayer.seekTo((int) time);
            } catch (IllegalStateException e) {
                e.printStackTrace();
            }
        });
    }

    @Override
    public void release() {
        if (mMediaHandler != null && mMediaHandlerThread != null && mediaPlayer != null) {//不知道有没有妖孽
            HandlerThread tmpHandlerThread = mMediaHandlerThread;
            MediaPlayer tmpMediaPlayer = mediaPlayer;
            JZMediaInterface.SAVED_SURFACE = null;

            mMediaHandler.post(() -> {
                tmpMediaPlayer.release();//release就不能放到主线程里,界面会卡顿
                tmpHandlerThread.quit();
            });
            mediaPlayer = null;
        }
    }
    
    @Override
    public long getCurrentPosition() {
        if (mediaPlayer != null) {
            return mediaPlayer.getCurrentPosition();
        } else {
            return 0;
        }
    }

    @Override
    public long getDuration() {
        if (mediaPlayer != null) {
            return mediaPlayer.getDuration();
        } else {
            return 0;
        }
    }

    @Override
    public void setVolume(float leftVolume, float rightVolume) {
        if (mMediaHandler == null) return;
        mMediaHandler.post(() -> {
            if (mediaPlayer != null) mediaPlayer.setVolume(leftVolume, rightVolume);
        });
    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    public void setSpeed(float speed) {
        PlaybackParams pp = mediaPlayer.getPlaybackParams();
        pp.setSpeed(speed);
        mediaPlayer.setPlaybackParams(pp);
    }

    @Override
    public void onPrepared(MediaPlayer mediaPlayer) {
        handler.post(() -> jzvd.onPrepared());//如果是mp3音频,走这里
    }

    @Override
    public void onCompletion(MediaPlayer mediaPlayer) {
        handler.post(() -> jzvd.onCompletion());
    }

    @Override
    public void onBufferingUpdate(MediaPlayer mediaPlayer, final int percent) {
        handler.post(() -> jzvd.setBufferProgress(percent));
    }

    @Override
    public void onSeekComplete(MediaPlayer mediaPlayer) {
        handler.post(() -> jzvd.onSeekComplete());
    }

    @Override
    public boolean onError(MediaPlayer mediaPlayer, final int what, final int extra) {
        handler.post(() -> jzvd.onError(what, extra));
        return true;
    }

    @Override
    public boolean onInfo(MediaPlayer mediaPlayer, final int what, final int extra) {
        handler.post(() -> {
            if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) {
                if (jzvd.state == Jzvd.STATE_PREPARING
                        || jzvd.state == Jzvd.STATE_PREPARING_CHANGE_URL) {
                    jzvd.onPrepared();
                }
            } else {
                jzvd.onInfo(what, extra);
            }
        });
        return false;
    }

    @Override
    public void onVideoSizeChanged(MediaPlayer mediaPlayer, int width, int height) {
        handler.post(() -> jzvd.onVideoSizeChanged(width, height));
    }

    @Override
    public void setSurface(Surface surface) {
        mediaPlayer.setSurface(surface);
    }

    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
        Log.i("GD", "======= onSurfaceTextureAvailable =======");
        if (SAVED_SURFACE == null) {
            SAVED_SURFACE = surface;
            prepare();
        } else {
            jzvd.textureView.setSurfaceTexture(SAVED_SURFACE);
        }
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {

    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        return false;
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surface) {

    }
}

6. VideoActivity.java

public class VideoActivity extends BaseActivity {
    @BindView(R.id.title_bar)
    TitleBar mTitleBar;

    @BindView(R.id.jz_video)
    JzvdStdAssert mJzVideo;

    public String localVideoPath;

    @Override
    protected int getLayoutId() {
        return R.layout.activity_video;
    }

    @Override
    protected void initView() {
        mTitleBar.setOnTitleBarListener(new OnTitleBarListener() {
            @Override
            public void onLeftClick(View view) {
                finish();
            }

            @Override
            public void onTitleClick(View view) {

            }

            @Override
            public void onRightClick(View view) {

            }
        });

        localVideoPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/DCIM/Camera/activity_local_video.mp4";

        //checkPermission
        int permission = ActivityCompat.checkSelfPermission(this, "android.permission.WRITE_EXTERNAL_STORAGE");
        if (permission != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{
                    "android.permission.READ_EXTERNAL_STORAGE",
                    "android.permission.WRITE_EXTERNAL_STORAGE"}, 1);
        }

        //cp video 防止视频被意外删除
        cpAssertVideoToLocalPath();

        mJzVideo.setUp("local_video.mp4", "4K视频", JzvdStd.SCREEN_NORMAL, JZMediaSystemAssertFolder.class);
        mJzVideo.posterImageView.setImageResource(R.mipmap.ic_cover);

    }

    @OnClick({R.id.iv_machine_no,R.id.iv_machine_ok})
    public void clicked(View view) {
        switch (view.getId()) {
            case R.id.iv_machine_no:
                MessageBean messageBean = new MessageBean();
                messageBean.setItemNum(5);
                messageBean.setStatus(500);
                EventBus.getDefault().post(messageBean);
                readyGo(MainActivity.class);
                finish();
                break;

            case R.id.iv_machine_ok:
                MessageBean message = new MessageBean();
                message.setItemNum(5);
                message.setStatus(200);
                EventBus.getDefault().post(message);
                readyGo(MainActivity.class);
                finish();
                break;

            default:
                break;
        }
    }

    public void cpAssertVideoToLocalPath() {
        if (new File(localVideoPath).exists()) return;

        try {
            InputStream myInput;
            OutputStream myOutput = new FileOutputStream(localVideoPath);
            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();
            Toast.makeText(this, "cp from assert to local path succ", Toast.LENGTH_SHORT).show();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onBackPressed() {
        if (Jzvd.backPress()) {
            return;
        }
        super.onBackPressed();
    }
    @Override
    protected void onPause() {
        super.onPause();
        JZUtils.clearSavedProgress(this, null);
        Jzvd.releaseAllVideos();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == 1) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                cpAssertVideoToLocalPath();
            } else {
                finish();
            }
        }
    }
}

五、播放本地音频

1. 效果图
在这里插入图片描述

2. JzvdStdMp3.java

/**
 * Created on 2022/3/14 14:56
 *
 * @author Gong Youqiang
 */
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_mp3;
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == cn.jzvd.R.id.poster &&
                (state == STATE_PLAYING ||
                        state == 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();
        posterImageView.setVisibility(View.VISIBLE);

    }

    @Override
    public void changeUiToPlayingClear() {
        super.changeUiToPlayingClear();
        posterImageView.setVisibility(View.VISIBLE);
    }

    @Override
    public void changeUiToPauseShow() {
        super.changeUiToPauseShow();
        posterImageView.setVisibility(View.VISIBLE);
    }

    @Override
    public void changeUiToPauseClear() {
        super.changeUiToPauseClear();
        posterImageView.setVisibility(View.VISIBLE);
    }

    @Override
    public void changeUiToComplete() {
        super.changeUiToComplete();
    }

    @Override
    public void changeUiToError() {
        super.changeUiToError();
    }
}

3. jz_layout_mp3.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/black"
    android:descendantFocusability="blocksDescendants">

    <FrameLayout
        android:id="@+id/surface_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </FrameLayout>


    <ImageView
        android:id="@+id/poster"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentStart="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentBottom="true"
        android:background="#000000"
        android:scaleType="fitCenter" />

    <LinearLayout
        android:id="@+id/layout_bottom"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_alignParentBottom="true"
        android:background="@drawable/jz_bottom_bg"
        android:gravity="center_vertical"
        android:orientation="horizontal"
        android:visibility="invisible">

        <TextView
            android:id="@+id/current"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="14dp"
            android:text="00:00"
            android:textColor="#ffffff" />

        <SeekBar
            android:id="@+id/bottom_seek_progress"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_weight="1.0"
            android:background="@null"
            android:max="100"
            android:maxHeight="1dp"
            android:minHeight="1dp"
            android:paddingLeft="12dp"
            android:paddingTop="8dp"
            android:paddingRight="12dp"
            android:paddingBottom="8dp"
            android:progressDrawable="@drawable/jz_bottom_seek_progress"
            android:thumb="@drawable/jz_bottom_seek_poster" />

        <TextView
            android:id="@+id/total"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="00:00"
            android:textColor="#ffffff" />

        <TextView
            android:id="@+id/clarity"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:clickable="true"
            android:paddingLeft="20dp"
            android:text="clarity"
            android:textAlignment="center"
            android:textColor="#ffffff" />

        <ImageView
            android:id="@+id/fullscreen"
            android:layout_width="52.5dp"
            android:layout_height="fill_parent"
            android:paddingLeft="14dp"
            android:paddingRight="14dp"
            android:scaleType="centerInside"
            android:src="@drawable/jz_enlarge" />
    </LinearLayout>

    <ProgressBar
        android:id="@+id/bottom_progress"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="1.5dp"
        android:layout_alignParentBottom="true"
        android:max="100"
        android:progressDrawable="@drawable/jz_bottom_progress" />

    <ImageView
        android:id="@+id/back_tiny"
        android:layout_width="24dp"
        android:layout_height="24dp"
        android:layout_marginLeft="6dp"
        android:layout_marginTop="6dp"
        android:background="@drawable/jz_click_back_tiny_selector"
        android:visibility="gone" />

    <RelativeLayout
        android:id="@+id/layout_top"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_alignParentStart="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:background="@drawable/jz_title_bg"
        android:gravity="center_vertical">

        <ImageView
            android:id="@+id/back"
            android:layout_width="23dp"
            android:layout_height="match_parent"
            android:layout_alignParentStart="true"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true"
            android:paddingStart="12dp"
            android:paddingLeft="12dp"
            android:scaleType="centerInside"
            android:src="@drawable/jz_click_back_selector" />

        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginStart="12dp"
            android:layout_marginLeft="12dp"
            android:layout_marginEnd="12dp"
            android:layout_marginRight="12dp"
            android:layout_toLeftOf="@+id/battery_time_layout"
            android:layout_toEndOf="@+id/back"
            android:layout_toRightOf="@+id/back"
            android:ellipsize="end"
            android:maxLines="2"
            android:textColor="#ffffff"
            android:textSize="18sp" />

        <LinearLayout
            android:id="@+id/battery_time_layout"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginEnd="14dp"
            android:layout_marginRight="14dp"
            android:gravity="center_vertical"
            android:orientation="vertical">

            <ImageView
                android:id="@+id/battery_level"
                android:layout_width="23dp"
                android:layout_height="10dp"
                android:layout_gravity="center_horizontal"
                android:background="@drawable/jz_battery_level_10" />

            <TextView
                android:id="@+id/video_current_time"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:gravity="center_vertical"
                android:maxLines="1"
                android:textColor="#ffffffff"
                android:textSize="12.0sp" />
        </LinearLayout>
    </RelativeLayout>

    <ProgressBar
        android:id="@+id/loading"
        android:layout_width="@dimen/jz_start_button_w_h_normal"
        android:layout_height="@dimen/jz_start_button_w_h_normal"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:indeterminateDrawable="@drawable/jz_loading"
        android:visibility="invisible" />

    <LinearLayout
        android:id="@+id/start_layout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:layout_gravity="center_vertical">

        <ImageView
            android:id="@+id/start"
            android:layout_width="@dimen/jz_start_button_w_h_normal"
            android:layout_height="@dimen/jz_start_button_w_h_normal"
            android:src="@drawable/jz_click_play_selector" />
    </LinearLayout>


    <TextView
        android:id="@+id/replay_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/start_layout"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="6dp"
        android:text="@string/replay"
        android:textColor="#ffffff"
        android:textSize="12sp"
        android:visibility="invisible" />

    <LinearLayout
        android:id="@+id/retry_layout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:gravity="center_horizontal"
        android:orientation="vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/video_loading_failed"
            android:textColor="@android:color/white"
            android:textSize="14sp" />

        <TextView
            android:id="@+id/retry_btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp"
            android:background="@drawable/jz_retry"
            android:paddingLeft="9dp"
            android:paddingTop="4dp"
            android:paddingRight="9dp"
            android:paddingBottom="4dp"
            android:text="@string/click_to_restart"
            android:textColor="@android:color/white"
            android:textSize="14sp" />
    </LinearLayout>
</RelativeLayout>

4. 使用

public class MachineActivity extends BaseActivity{

    @BindView(R.id.title_bar)
    TitleBar mTitleBar;

    @BindView(R.id.jz_mp3)
    JzvdStdMp3 mStdMp3;

    @Override
    protected int getLayoutId() {
        return R.layout.activity_machine;
    }

    @Override
    protected void initView() {
        mTitleBar.setOnTitleBarListener(new OnTitleBarListener() {
            @Override
            public void onLeftClick(View view) {
                finish();
            }

            @Override
            public void onTitleClick(View view) {

            }

            @Override
            public void onRightClick(View view) {

            }
        });

        mStdMp3.setUp("machine.mp3", "机震测试", JzvdStd.SCREEN_NORMAL,JZMediaSystemAssertFolder.class);
        mStdMp3.posterImageView.setImageResource(R.mipmap.ic_machine_thump);
    }

   
    @Override
    public void onBackPressed() {
        if (Jzvd.backPress()) {
            return;
        }
        super.onBackPressed();
    }
    @Override
    protected void onPause() {
        super.onPause();
        JZUtils.clearSavedProgress(this, null);
        Jzvd.releaseAllVideos();
    }

}
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kevin-Dev

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值