Improve player

This commit is contained in:
tom79 2019-06-26 18:48:07 +02:00
parent 2ec1ab54d2
commit 47e28fc642
5 changed files with 248 additions and 9 deletions

View File

@ -21,6 +21,9 @@
package="app.fedilab.android">
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.INTERNET" />

View File

@ -19,13 +19,18 @@ import android.Manifest;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.RectF;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.os.Handler;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
@ -34,13 +39,19 @@ import android.webkit.WebView;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.MediaController;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.VideoView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.transition.Transition;
import com.cleveroad.audiovisualization.DbmHandler;
import com.cleveroad.audiovisualization.GLAudioVisualizationView;
import com.cleveroad.audiovisualization.SpeechRecognizerDbmHandler;
import com.cleveroad.audiovisualization.VisualizerDbmHandler;
import com.github.chrisbanes.photoview.OnMatrixChangedListener;
import com.github.chrisbanes.photoview.PhotoView;
import com.google.android.exoplayer2.ExoPlayerFactory;
@ -54,9 +65,12 @@ import com.google.android.exoplayer2.util.Util;
import com.gw.swipeback.SwipeBackLayout;
import java.io.File;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
import javax.net.ssl.HttpsURLConnection;
@ -69,8 +83,15 @@ import app.fedilab.android.webview.MastalabWebChromeClient;
import app.fedilab.android.webview.MastalabWebViewClient;
import app.fedilab.android.R;
import app.fedilab.android.interfaces.OnDownloadInterface;
import cafe.adriel.androidaudiorecorder.AndroidAudioRecorder;
import cafe.adriel.androidaudiorecorder.AudioRecorderActivity;
import cafe.adriel.androidaudiorecorder.VisualizerHandler;
import omrecorder.AudioChunk;
import omrecorder.PullTransport;
import static app.fedilab.android.helper.Helper.changeDrawableColor;
import static cafe.adriel.androidaudiorecorder.Util.formatSeconds;
import static cafe.adriel.androidaudiorecorder.Util.getDarkerColor;
/**
@ -78,7 +99,7 @@ import static app.fedilab.android.helper.Helper.changeDrawableColor;
* Media Activity
*/
public class MediaActivity extends BaseActivity implements OnDownloadInterface {
public class MediaActivity extends BaseActivity implements OnDownloadInterface, PullTransport.OnAudioChunkPulledListener, MediaPlayer.OnCompletionListener {
private RelativeLayout loader;
@ -105,6 +126,12 @@ public class MediaActivity extends BaseActivity implements OnDownloadInterface {
SwipeBackLayout mSwipeBackLayout;
private float imageScale = 0;
private RelativeLayout action_bar_container;
private VisualizerHandler visualizerHandler;
private TextView statusView;
private TextView timerView;
private ImageButton playView;
private GLAudioVisualizationView visualizerView;
private enum actionSwipe{
RIGHT_TO_LEFT,
LEFT_TO_RIGHT,
@ -116,6 +143,12 @@ public class MediaActivity extends BaseActivity implements OnDownloadInterface {
private SimpleExoPlayer player;
private boolean isSHaring;
private String instance;
private RelativeLayout content_audio;
private MediaPlayer playeraudio;
private Timer timer;
private int playerSecondsElapsed;
private static final Handler HANDLER = new Handler();
private String url;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -126,7 +159,7 @@ public class MediaActivity extends BaseActivity implements OnDownloadInterface {
super.onCreate(savedInstanceState);
hideSystemUI();
setContentView(R.layout.activity_media);
action_bar_container = (RelativeLayout) findViewById(R.id.action_bar_container);
action_bar_container = findViewById(R.id.action_bar_container);
mSwipeBackLayout = new SwipeBackLayout(MediaActivity.this);
mSwipeBackLayout.setDirectionMode(SwipeBackLayout.FROM_TOP);
mSwipeBackLayout.setMaskAlpha(125);
@ -147,6 +180,7 @@ public class MediaActivity extends BaseActivity implements OnDownloadInterface {
}
}
});
instance = Helper.getLiveInstance(MediaActivity.this);
mSwipeBackLayout.attachToActivity(this);
attachments = getIntent().getParcelableArrayListExtra("mediaArray");
@ -170,7 +204,7 @@ public class MediaActivity extends BaseActivity implements OnDownloadInterface {
media_close = findViewById(R.id.media_close);
progress = findViewById(R.id.loader_progress);
webview_video = findViewById(R.id.webview_video);
content_audio = findViewById(R.id.content_audio);
media_save.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
@ -281,7 +315,10 @@ public class MediaActivity extends BaseActivity implements OnDownloadInterface {
super.onSaveInstanceState(outState);
}
@Override
public void onCompletion(MediaPlayer mp) {
}
/**
* Manage touch event
* Allows to swipe from timelines
@ -443,7 +480,6 @@ public class MediaActivity extends BaseActivity implements OnDownloadInterface {
);
break;
case "video":
case "audio":
case "gifv":
pbar_inf.setIndeterminate(false);
pbar_inf.setScaleY(3f);
@ -507,9 +543,137 @@ public class MediaActivity extends BaseActivity implements OnDownloadInterface {
webview_video.setWebViewClient(new MastalabWebViewClient(MediaActivity.this));
webview_video.loadUrl(attachment.getUrl());
break;
case "audio":
int color = getIntent().getIntExtra("color", Color.BLACK);
visualizerView = new GLAudioVisualizationView.Builder(this)
.setLayersCount(1)
.setWavesCount(6)
.setWavesHeight(R.dimen.aar_wave_height)
.setWavesFooterHeight(R.dimen.aar_footer_height)
.setBubblesPerLayer(20)
.setBubblesSize(R.dimen.aar_bubble_size)
.setBubblesRandomizeSize(true)
.setBackgroundColor(getDarkerColor(color))
.setLayerColors(new int[]{color})
.build();
statusView = findViewById(R.id.status);
timerView = findViewById(R.id.timer);
playView = findViewById(R.id.play);
content_audio.setBackgroundColor(getDarkerColor(color));
content_audio.addView(visualizerView, 0);
playView.setVisibility(View.INVISIBLE);
this.url = attachment.getUrl();
startPlaying();
break;
}
}
public void togglePlaying(View v){
HANDLER.postDelayed(new Runnable() {
@Override
public void run() {
if(isPlaying()){
stopPlaying();
} else {
startPlaying();
}
}
}, 100);
}
private void startPlaying(){
try {
playeraudio = new MediaPlayer();
playeraudio.setDataSource(url);
playeraudio.prepare();
playeraudio.start();
visualizerView.linkTo(DbmHandler.Factory.newVisualizerHandler(this, playeraudio));
visualizerView.post(new Runnable() {
@Override
public void run() {
playeraudio.setOnCompletionListener(MediaActivity.this);
}
});
timerView.setText("00:00:00");
playView.setVisibility(View.VISIBLE);
statusView.setText(R.string.aar_playing);
statusView.setVisibility(View.VISIBLE);
playView.setImageResource(R.drawable.aar_ic_stop);
playerSecondsElapsed = 0;
startTimer();
} catch (Exception e){
e.printStackTrace();
}
}
private void stopPlaying(){
statusView.setText("");
statusView.setVisibility(View.INVISIBLE);
playView.setImageResource(R.drawable.aar_ic_play);
visualizerView.release();
if(visualizerHandler != null) {
visualizerHandler.stop();
}
if(playeraudio != null){
try {
playeraudio.pause();
} catch (Exception ignored){ }
}
stopTimer();
}
private void startTimer(){
stopTimer();
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
updateTimer();
}
}, 0, 1000);
}
private void updateTimer() {
runOnUiThread(new Runnable() {
@Override
public void run() {
playerSecondsElapsed++;
timerView.setText(formatSeconds(playerSecondsElapsed));
}
});
}
private void stopTimer(){
if (timer != null) {
timer.cancel();
timer.purge();
timer = null;
}
}
private boolean isPlaying(){
try {
return playeraudio != null && playeraudio.isPlaying();
} catch (Exception e){
return false;
}
}
@Override
public void onAudioChunkPulled(AudioChunk audioChunk) {
float amplitude = (float) audioChunk.maxAmplitude();
visualizerHandler.onDataReceived(amplitude);
}
@Override
public void onDownloaded(String path, String originUrl, Error error) {
@ -545,6 +709,9 @@ public class MediaActivity extends BaseActivity implements OnDownloadInterface {
if( player != null) {
player.setPlayWhenReady(false);
}
if( playeraudio != null) {
playeraudio.pause();
}
}
@Override
@ -553,6 +720,9 @@ public class MediaActivity extends BaseActivity implements OnDownloadInterface {
if( player != null) {
player.setPlayWhenReady(true);
}
if( playeraudio != null) {
playeraudio.start();
}
}

View File

@ -884,6 +884,8 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
Helper.changeDrawableColor(context, R.drawable.ic_remove_red_eye, R.color.dark_text);
Helper.changeDrawableColor(context, R.drawable.ic_repeat_head_toot, R.color.black_text_toot_header);
Helper.changeDrawableColor(context, R.drawable.ic_soundcloud, R.color.black_text_toot_header);
Helper.changeDrawableColor(context, R.drawable.ic_fetch_more, R.color.dark_icon);
holder.status_cardview_title.setTextColor(ContextCompat.getColor(context, R.color.black_text_toot_header));
holder.status_cardview_content.setTextColor(ContextCompat.getColor(context, R.color.dark_icon));
@ -906,7 +908,7 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
holder.status_reply_count.setTextColor(ContextCompat.getColor(context, R.color.action_dark));
holder.status_favorite_count.setTextColor(ContextCompat.getColor(context, R.color.action_dark));
holder.status_reblog_count.setTextColor(ContextCompat.getColor(context, R.color.action_dark));
Helper.changeDrawableColor(context, R.drawable.ic_soundcloud, R.color.action_dark);
Helper.changeDrawableColor(context, R.drawable.ic_repeat_head_toot, R.color.dark_text_toot_header);
Helper.changeDrawableColor(context, R.drawable.ic_photo, R.color.mastodonC4);
@ -933,6 +935,7 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
Helper.changeDrawableColor(context, R.drawable.ic_repeat, R.color.action_light);
Helper.changeDrawableColor(context, R.drawable.ic_plus_one, R.color.action_light);
Helper.changeDrawableColor(context, R.drawable.ic_pin_drop, R.color.action_light);
Helper.changeDrawableColor(context, R.drawable.ic_soundcloud, R.color.action_light);
holder.status_reply_count.setTextColor(ContextCompat.getColor(context, R.color.action_light));
holder.status_favorite_count.setTextColor(ContextCompat.getColor(context, R.color.action_light));
holder.status_reblog_count.setTextColor(ContextCompat.getColor(context, R.color.action_light));
@ -2968,7 +2971,7 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
if( !blur) {
Glide.with(imageView.getContext())
.asBitmap()
.load(url)
.load( !attachment.getType().toLowerCase().equals("audio")?url:R.drawable.ic_soundcloud)
.thumbnail(0.1f)
.apply(new RequestOptions().transforms(new CenterCrop(), new RoundedCorners(10)))
.into(new SimpleTarget<Bitmap>() {
@ -2991,7 +2994,7 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
}else{
Glide.with(imageView.getContext())
.asBitmap()
.load(url)
.load(!attachment.getType().toLowerCase().equals("audio")?url:R.drawable.ic_soundcloud)
.thumbnail(0.1f)
.apply(new RequestOptions().transforms(new BlurTransformation(50,3), new RoundedCorners(10)))
.into(new SimpleTarget<Bitmap>() {
@ -3016,14 +3019,14 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct
if (!url.trim().contains("missing.png") && !((Activity) context).isFinishing()) {
if( !blur) {
Glide.with(imageView.getContext())
.load(url)
.load(!attachment.getType().toLowerCase().equals("audio")?url:R.drawable.ic_soundcloud)
.thumbnail(0.1f)
.apply(new RequestOptions().transforms(new CenterCrop(), new RoundedCorners(10)))
.transition(DrawableTransitionOptions.withCrossFade())
.into(imageView);
}else{
Glide.with(imageView.getContext())
.load(url)
.load(!attachment.getType().toLowerCase().equals("audio")?url:R.drawable.ic_soundcloud)
.thumbnail(0.1f)
.apply(new RequestOptions().transforms(new BlurTransformation(50,3), new RoundedCorners(10)))
.transition(DrawableTransitionOptions.withCrossFade())

View File

@ -0,0 +1,4 @@
<vector android:height="24dp" android:viewportHeight="90"
android:viewportWidth="90" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M0,54c0,3 1.4,5.8 3.6,7.6V46.4C1.4,48.3 0,51 0,54M7.3,44.4v19.2c0.9,0.2 1.8,0.4 2.8,0.4h1V44.1c-0.3,0 -0.6,0 -1,0C9.2,44 8.2,44.2 7.3,44.4M15.7,45.7c-0.3,-0.2 -0.5,-0.3 -0.8,-0.5V64h3.8V38.9C17.2,40.8 16.1,43.2 15.7,45.7M22.4,35.3V64h3.8V33.5C24.9,33.9 23.6,34.6 22.4,35.3M30,32.7V64h3.8V32.8c-0.8,-0.1 -1.6,-0.2 -2.4,-0.2C30.9,32.7 30.4,32.7 30,32.7M39.6,34.9c-1.2,-0.7 -2.6,-1.3 -4,-1.7V64h5.7V32.6C40.7,33.4 40.1,34.1 39.6,34.9M43.2,30.8V64H79v0c7.5,-0.5 11,-5.2 11,-10.9c0,-6 -4.6,-10.9 -10.7,-10.9c-1.6,0 -2.9,0.3 -4.2,0.9c-1,-9.6 -9.1,-17.1 -19.1,-17.1C51,26 46.6,27.8 43.2,30.8"/>
</vector>

View File

@ -95,6 +95,65 @@
android:textColor="#ffffffff"
/>
</FrameLayout>
<RelativeLayout
android:id="@+id/content_audio"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="50dp"
android:orientation="vertical">
<TextView
android:id="@+id/status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="-10dp"
android:textSize="20sp"
android:textColor="@android:color/white"
android:fontFamily="sans-serif-light"
android:visibility="invisible"/>
<TextView
android:id="@+id/timer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="60sp"
android:textColor="@android:color/white"
android:fontFamily="sans-serif-thin"
android:text="00:00:00"/>
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="@dimen/aar_footer_height"
android:layout_alignParentBottom="true">
<ImageButton
android:id="@+id/play"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_centerVertical="true"
android:layout_centerInParent="true"
android:layout_marginTop="50dp"
android:padding="10dp"
android:scaleType="fitCenter"
android:src="@drawable/aar_ic_play"
android:onClick="togglePlaying"
style="@style/Widget.AppCompat.Button.Borderless"/>
</RelativeLayout>
</RelativeLayout>
<com.google.android.exoplayer2.ui.SimpleExoPlayerView
android:visibility="gone"
android:id="@+id/media_video"