use ExoPlayer for video playback

This commit is contained in:
Christian Schneppe 2020-01-31 14:28:27 +01:00
parent 6bb9db3686
commit 83c976f2d7
No known key found for this signature in database
GPG key ID: F30B8D686B44D87E
8 changed files with 71 additions and 43 deletions

View file

@ -71,7 +71,8 @@ dependencies {
implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'com.davemorrissey.labs:subsampling-scale-image-view:3.10.0'
implementation project(':libs:fullscreenvideoview')
implementation 'com.google.android.exoplayer:exoplayer-core:2.11.1'
implementation 'com.google.android.exoplayer:exoplayer-ui:2.11.1'
implementation 'pub.devrel:easypermissions:3.0.0' // version >= 3.0.0 needs android X libraries
implementation 'com.wefika:flowlayout:0.4.1'
implementation 'com.googlecode.ez-vcard:ez-vcard:0.10.5'

View file

@ -19,11 +19,9 @@ import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.media.MediaMetadataRetriever;
import android.media.MediaMuxer;
import android.os.Build;
import android.util.Log;
import net.ypresto.androidtranscoder.format.MediaFormatStrategy;
import net.ypresto.androidtranscoder.utils.ISO6709LocationParser;
import net.ypresto.androidtranscoder.utils.MediaExtractorUtils;
import java.io.FileDescriptor;
@ -139,18 +137,6 @@ public class MediaTranscoderEngine {
// skip
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
String locationString = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_LOCATION);
if (locationString != null) {
float[] location = new ISO6709LocationParser().parse(locationString);
if (location != null) {
mMuxer.setLocation(location[0], location[1]);
} else {
Log.d(TAG, "Failed to parse the location metadata: " + locationString);
}
}
}
try {
mDurationUs = Long.parseLong(mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)) * 1000;
} catch (NumberFormatException e) {

View file

@ -18,9 +18,10 @@ package net.ypresto.androidtranscoder.format;
import android.media.MediaCodecInfo;
import android.media.MediaFormat;
import android.os.Build;
import androidx.annotation.RequiresApi;
import android.util.Log;
import androidx.annotation.RequiresApi;
class AndroidStandardFormatStrategy implements MediaFormatStrategy {
public static final int AUDIO_BITRATE_AS_IS = -1;
public static final int AUDIO_CHANNELS_AS_IS = -1;

View file

@ -182,10 +182,6 @@ public class AttachFileToConversationRunnable implements Runnable, MediaTranscod
}
}
private String getVideoCompression() {
return getVideoCompression(mXmppConnectionService);
}
public static String getVideoCompression(final Context context) {
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
return preferences.getString("video_compression", context.getResources().getString(R.string.video_compression));

View file

@ -22,7 +22,6 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.webkit.MimeTypeMap;
import android.widget.ImageView;
import android.widget.Toast;
import androidx.appcompat.app.ActionBar;
@ -30,10 +29,17 @@ import androidx.appcompat.app.AlertDialog;
import androidx.databinding.DataBindingUtil;
import com.davemorrissey.labs.subscaleview.ImageSource;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.util.Util;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
@ -49,7 +55,7 @@ import static de.pixart.messenger.persistance.FileBackend.close;
public class MediaViewerActivity extends XmppActivity implements AudioManager.OnAudioFocusChangeListener {
Integer oldOrientation;
ImageView mFullscreenbutton;
SimpleExoPlayer player;
Uri mFileUri;
File mFile;
int height = 0;
@ -86,8 +92,6 @@ public class MediaViewerActivity extends XmppActivity implements AudioManager.On
showFab();
return super.onDown(e);
}
});
ActionBar actionBar = getSupportActionBar();
@ -104,7 +108,6 @@ public class MediaViewerActivity extends XmppActivity implements AudioManager.On
getWindow().setAttributes(layout);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
mFullscreenbutton = findViewById(R.id.vcv_img_fullscreen);
binding.speedDial.inflate(R.menu.media_viewer);
binding.speedDial.setOnActionSelectedListener(actionItem -> {
switch (actionItem.getId()) {
@ -226,9 +229,8 @@ public class MediaViewerActivity extends XmppActivity implements AudioManager.On
}
}
private void DisplayImage(final File file, final Uri FileUri) {
boolean gif = false;
gif = "image/gif".equalsIgnoreCase(getMimeType(file.toString()));
private void DisplayImage(final File file, final Uri uri) {
final boolean gif = "image/gif".equalsIgnoreCase(getMimeType(file.toString()));
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(new File(file.getPath()).getAbsolutePath(), options);
@ -242,12 +244,11 @@ public class MediaViewerActivity extends XmppActivity implements AudioManager.On
try {
if (gif) {
binding.messageGifView.setVisibility(View.VISIBLE);
binding.messageGifView.setImageURI(FileUri);
binding.messageGifView.setImageURI(uri);
binding.messageGifView.setOnTouchListener((view, motionEvent) -> gestureDetector.onTouchEvent(motionEvent));
} else {
binding.messageImageView.setVisibility(View.VISIBLE);
binding.messageImageView.setOrientation(rotation);
binding.messageImageView.setImage(ImageSource.uri(FileUri));
binding.messageImageView.setImage(ImageSource.uri(uri));
binding.messageImageView.setOnTouchListener((view, motionEvent) -> gestureDetector.onTouchEvent(motionEvent));
}
} catch (Exception e) {
@ -262,7 +263,7 @@ public class MediaViewerActivity extends XmppActivity implements AudioManager.On
retriever.setDataSource(uri.getPath());
Bitmap bitmap = null;
try {
bitmap = retriever.getFrameAtTime();
bitmap = retriever.getFrameAtTime(0);
height = bitmap.getHeight();
width = bitmap.getWidth();
} catch (Exception e) {
@ -273,21 +274,35 @@ public class MediaViewerActivity extends XmppActivity implements AudioManager.On
bitmap.recycle();
}
}
rotation = Integer.valueOf(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION));
try {
rotation = Integer.valueOf(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION));
} catch (Exception e) {
rotation = 0;
}
Log.d(Config.LOGTAG, "Video height: " + height + ", width: " + width + ", rotation: " + rotation);
if (useAutoRotateScreen()) {
rotateScreen(width, height, rotation);
}
binding.messageVideoView.setVisibility(View.VISIBLE);
binding.messageVideoView.setVideoURI(uri);
mFullscreenbutton.setVisibility(View.INVISIBLE);
binding.messageVideoView.setShouldAutoplay(true);
player = new SimpleExoPlayer.Builder(this).build();
player.setPlayWhenReady(true);
player.addListener(new SimpleExoPlayer.EventListener() {
@Override
public void onPlayerError(ExoPlaybackException error) {
open();
}
});
player.setRepeatMode(Player.REPEAT_MODE_OFF);
binding.messageVideoView.setPlayer(player);
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "de.pixart.messenger"));
MediaSource videoSource = new ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(uri);
player.prepare(videoSource);
requestAudioFocus();
setVolumeControlStream(AudioManager.STREAM_MUSIC);
binding.messageVideoView.setOnTouchListener((view, motionEvent) -> gestureDetector.onTouchEvent(motionEvent));
} catch (Exception e) {
open();
e.printStackTrace();
open();
}
}
@ -331,6 +346,34 @@ public class MediaViewerActivity extends XmppActivity implements AudioManager.On
}
}
private void pausePlayer() {
if (isVideo && isPlaying()) {
player.setPlayWhenReady(false);
player.getPlaybackState();
}
}
private void startPlayer() {
if (isVideo && !isPlaying()) {
player.setPlayWhenReady(true);
player.getPlaybackState();
}
}
private void stopPlayer() {
if (isVideo && isPlaying()) {
player.stop(true);
player.release();
}
}
private boolean isPlaying() {
return player != null
&& player.getPlaybackState() != Player.STATE_ENDED
&& player.getPlaybackState() != Player.STATE_IDLE
&& player.getPlayWhenReady();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
@ -344,13 +387,13 @@ public class MediaViewerActivity extends XmppActivity implements AudioManager.On
}
getWindow().setAttributes(layout);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
binding.messageVideoView.setShouldAutoplay(true);
startPlayer();
super.onResume();
}
@Override
public void onPause() {
binding.messageVideoView.reset();
pausePlayer();
WindowManager.LayoutParams layout = getWindow().getAttributes();
if (useMaxBrightness()) {
layout.screenBrightness = -1;
@ -363,7 +406,7 @@ public class MediaViewerActivity extends XmppActivity implements AudioManager.On
@Override
public void onStop() {
binding.messageVideoView.reset();
stopPlayer();
releaseAudiFocus();
WindowManager.LayoutParams layout = getWindow().getAttributes();
if (useMaxBrightness()) {

View file

@ -376,6 +376,7 @@ public final class MimeUtils {
add("video/mpeg", "mpg");
add("video/mpeg", "mpe");
add("video/mp4", "mp4");
add("video/mp4", "gifv");
add("video/mpeg", "VOB");
add("video/quicktime", "qt");
add("video/quicktime", "mov");

View file

@ -22,7 +22,7 @@
android:adjustViewBounds="true"
android:visibility="gone" />
<com.github.rtoshiro.view.video.FullscreenVideoLayout
<com.google.android.exoplayer2.ui.SimpleExoPlayerView
android:id="@+id/messageVideoView"
android:layout_width="match_parent"
android:layout_height="match_parent"

View file

@ -38,7 +38,7 @@
\n\nhttps://github.com/square/picasso\n(Apache License, Version 2.0)
\n\nhttps://github.com/davemorrissey/subsampling-scale-image-view\n(Apache License, Version 2.0)
\n\nhttps://github.com/koral--/android-gif-drawable\n(The MIT License (MIT))
\n\nhttps://github.com/rtoshiro/FullscreenVideoView\n(Apache License, Version 2.0)
\n\nhttps://github.com/google/ExoPlayer\n(Apache License, Version 2.0)
\n\nhttps://github.com/mangstadt/ez-vcard\n(FreeBSD)
\n\nhttps://github.com/googlesamples/easypermissions\n(Apache License, Version 2.0)
\n\nhttps://github.com/blazsolar/FlowLayout\n(Apache License, Version 2.0)