相关文章推荐
豪爽的牛肉面  ·  WPS ...·  1 年前    · 

谷歌的一个在线播放视频的框架,使用起来非常简单

1.官方地址: https://github.com/google/ExoPlayer 有兴趣的,可以去官方地址,看一下框架的源码,本例子只是介绍简单使用

2.我的项目地址: https://github.com/wrs13634194612/ExoPlayerTest

3.运行效果图:

4.首先就是引用,在builder.gradle引入框架,或者直接使用jar包,本例子是使用的jar包

    implementation 'com.google.android.exoplayer:exoplayer-core:2.7.3'
    implementation 'com.google.android.exoplayer:exoplayer-ui:2.7.3'
    implementation 'com.google.android.exoplayer:exoplayer-core:2.7.3'

引入jar:

implementation files('libs/exoplayer.jar')

5.清单文件,设置一下硬件加速解码和网络请求权限,并且设置activity横屏

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.example.administrator.testz"
    tools:ignore="MissingLeanbackLauncher">
    <uses-feature
        android:name="android.software.leanback"
        android:required="false" />
    <uses-feature
        android:name="android.hardware.touchscreen"
        android:required="false" />
    <uses-permission android:name="android.permission.INTERNET" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        tools:ignore="GoogleAppIndexingWarning">
        <activity android:name=".MainActivity"
            android:screenOrientation="landscape">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

6.布局:简单写一个播放器控件,展示视频播放内容

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:keepScreenOn="true">
    <com.google.android.exoplayer.VideoSurfaceView
        android:id="@+id/surface_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center" />
        android:id="@+id/shutter"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/black" />
</FrameLayout>

7.创建一个视频类,

package com.example.administrator.testz;
public class Video {
    public static final String INTENT_EXTRA_VIDEO = "INTENT_EXTRA_VIDEO";
    private long id;
    private int year;
    private int rating;
    private String description;
    private String title;
    private String thumbUrl;
    private String contentUrl;
    private String category;
    private String tags;
    public long getId() {
        return id;
    public void setId(long id) {
        this.id = id;
    public int getYear() {
        return year;
    public void setYear(int year) {
        this.year = year;
    public int getRating() {
        return rating;
    public void setRating(int rating) {
        this.rating = rating;
    public String getDescription() {
        return description;
    public void setDescription(String description) {
        this.description = description;
    public String getTitle() {
        return title;
    public void setTitle(String title) {
        this.title = title;
    public String getThumbUrl() {
        return thumbUrl;
    public void setThumbUrl(String thumbUrl) {
        this.thumbUrl = thumbUrl;
    public String getContentUrl() {
        return contentUrl;
    public void setContentUrl(String contentUrl) {
        this.contentUrl = contentUrl;
    public String getCategory() {
        return category;
    public void setCategory(String category) {
        this.category = category;
    public String getTags() {
        return tags;
    public void setTags(String tags) {
        this.tags = tags;

8.创建ExoPlayer对象,获取视频数据,展示,具体的网络请求,视频的编解码,都已经封装好了,记得退出activity需要清空ExoPlayer对象,避免内存泄漏

package com.example.administrator.testz;
import androidx.appcompat.app.AppCompatActivity;
import android.media.MediaCodec;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.View;
import android.widget.MediaController;
import android.widget.Toast;
import com.google.android.exoplayer.ExoPlaybackException;
import com.google.android.exoplayer.ExoPlayer;
import com.google.android.exoplayer.FrameworkSampleSource;
import com.google.android.exoplayer.MediaCodecAudioTrackRenderer;
import com.google.android.exoplayer.MediaCodecTrackRenderer;
import com.google.android.exoplayer.MediaCodecVideoTrackRenderer;
import com.google.android.exoplayer.SampleSource;
import com.google.android.exoplayer.TrackRenderer;
import com.google.android.exoplayer.VideoSurfaceView;
import com.google.android.exoplayer.util.PlayerControl;
public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback,
        ExoPlayer.Listener, MediaCodecVideoTrackRenderer.EventListener {
    private static final int RENDERER_COUNT = 2;
    private static final String TAG = "MainActivity";
    private Video mViedeo;
    private MediaController mediaController;
    private View shutterView;
    private VideoSurfaceView surfaceView;
    private ExoPlayer player;
    private MediaCodecVideoTrackRenderer videoRenderer;
    private boolean autoPlay;
    private String mUrl = "https://v-cdn.zjol.com.cn/280443.mp4";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_player);
        mViedeo = (Video)getIntent().getSerializableExtra(Video.INTENT_EXTRA_VIDEO);
        View root = findViewById(R.id.root);
        shutterView = findViewById(R.id.shutter);
        surfaceView = (VideoSurfaceView)findViewById(R.id.surface_view);
        mediaController = new MediaController(this);
        mediaController.setPadding(48,27,48,27);
        mediaController.setAnchorView(root);
        surfaceView.getHolder().addCallback(this);
        preparePlayer();
    private void preparePlayer() {
        SampleSource sampleSource = new FrameworkSampleSource(this, Uri.parse(mUrl),null,RENDERER_COUNT);
        videoRenderer = new MediaCodecVideoTrackRenderer(sampleSource,MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT);
        TrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource);
        player = ExoPlayer.Factory.newInstance(RENDERER_COUNT,1000,5000);
        player.addListener(this);
        mediaController.setMediaPlayer(new PlayerControl(player));
        mediaController.setEnabled(true);
        player.prepare(videoRenderer,audioRenderer);
    @Override
    protected void onResume() {
        super.onResume();
    @Override
    protected void onPause() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            requestVisibleBehind(true);
        super.onPause();
    // 当此activity的半透明activity变得不透明或正在启动另一个activity时调用。
    @Override
    public void onVisibleBehindCanceled() {
        super.onVisibleBehindCanceled();
        if (player!=null){
            player.release();
            player = null;
        videoRenderer = null;
        shutterView.setVisibility(View.VISIBLE);
    @Override
    protected void onStop() {
        super.onStop();
        if (player!=null){
            player.release();
            player = null;
        videoRenderer = null;
        shutterView.setVisibility((View.VISIBLE));
    private void maybeStartPlayback(){
        Log.d(TAG, "maybeStartPlayback");
        Surface surface = surfaceView.getHolder().getSurface();
        if (videoRenderer == null || surface == null || !surface.isValid()){
            return;
        player.sendMessage(videoRenderer,MediaCodecVideoTrackRenderer.MSG_SET_SURFACE,surface);
        if (autoPlay){
            player.setPlayWhenReady(true);
            autoPlay = false;
    private void onError(Exception e){
        Log.e(TAG,"Player failed",e);
        Toast.makeText(getApplicationContext(),"Playback failed",Toast.LENGTH_SHORT).show();
        finish();
    @Override
    public void surfaceCreated(SurfaceHolder surfaceHolder) {
        Log.e(TAG,"maybeStartPlayback");
        maybeStartPlayback();
    @Override
    public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
    @Override
    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
        if (videoRenderer != null){
            player.blockingSendMessage(videoRenderer,MediaCodecVideoTrackRenderer.MSG_SET_SURFACE,null);
    @Override
    public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
        Log.e(TAG,"player state"+playbackState);
        if (playbackState == ExoPlayer.STATE_READY){
            shutterView.setVisibility(View.GONE);
            mediaController.show(0);
    @Override
    public void onPlayWhenReadyCommitted() {
    @Override
    public void onPlayerError(ExoPlaybackException e) {
        onError(e);
    @Override
    public void onDroppedFrames(int count, long elapsed) {
        Log.e(TAG,"Dropped frames:"+count);
    @Override
    public void onVideoSizeChanged(int width, int height, float v) {
        surfaceView.setVideoWidthHeightRatio(height==0?1:(float)width/height);
    @Override
    public void onDrawnToSurface(Surface surface) {
        shutterView.setVisibility(View.GONE);
        mediaController.show(0);
    @Override
    public void onDecoderInitializationError(MediaCodecTrackRenderer.DecoderInitializationException e) {
    @Override
    public void onCryptoError(MediaCodec.CryptoException e) {
    @Override
    public void onDecoderInitialized(String s, long l, long l1) {
                            
java开发截图怎么变成文本 javaoffer截图

 下方为所剪切的图片,点击保存,可以选择一个“.jpg”图片作为保存路径设计思路:1、主面板的绘制,就是上方面板2、点击“屏幕截图”时的监听器设置2.1、首先隐藏主面板,对后方的屏幕页面进行图片截取操作2.2、主要设计以及绘制在CaptureFrame ()类,注释已加 package my; import java.awt.Color; import java.awt.Di

字符转数字 python 字符转数字js

  //--------------------字符串转数字---------------------------var s = "234"; //1、纯数字转换 //字符串在运算操作中会被当做数字类型来处理 s *= 1; //2 字符前加“+” console.log(+s); //string的两个转换函数,只对string有效