谷歌的一个在线播放视频的框架,使用起来非常简单
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有效