Skip to content
This repository has been archived by the owner on Apr 12, 2022. It is now read-only.

Commit

Permalink
Add internal playback of audio files
Browse files Browse the repository at this point in the history
Signed-off-by: Manuel Stahl <[email protected]>
  • Loading branch information
awesome-manuel committed Aug 19, 2019
1 parent f23e9d8 commit c0807ab
Show file tree
Hide file tree
Showing 9 changed files with 249 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import android.graphics.Point;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
Expand Down Expand Up @@ -882,6 +883,8 @@ public void onBingRulesUpdate() {
*/
public void onPause() {
mEventFormattedTsMap.clear();

mMediasHelper.refreshPlayImageViews();
}

/**
Expand Down Expand Up @@ -951,9 +954,9 @@ public Event getCurrentSelectedEvent() {
*
* @param listener teh events listener
*/
public void setVectorMessagesAdapterActionsListener(IMessagesAdapterActionsListener listener) {
public void setVectorMessagesAdapterActionsListener(IMessagesAdapterActionsListener listener, HashMap<String, MediaPlayer> mediaPlayers) {
mVectorMessagesAdapterEventsListener = listener;
mMediasHelper.setVectorMessagesAdapterActionsListener(listener);
mMediasHelper.setVectorMessagesAdapterActionsListener(listener, mediaPlayers);
mHelper.setVectorMessagesAdapterActionsListener(listener);

if (null != mLinkMovementMethod) {
Expand Down Expand Up @@ -1589,6 +1592,7 @@ private View getFileView(final int position, View convertView, ViewGroup parent)

mMediasHelper.managePendingFileDownload(convertView, event, fileMessage, position);
mMediasHelper.managePendingUpload(convertView, event, ROW_TYPE_FILE, fileMessage.url);
mMediasHelper.managePlayback(convertView, event, ROW_TYPE_FILE, fileMessage.url);

View fileLayout = convertView.findViewById(R.id.messagesAdapter_file_layout);
manageSubView(position, convertView, fileLayout, ROW_TYPE_FILE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import android.content.Context;
import android.graphics.Color;
import android.media.ExifInterface;
import android.media.MediaPlayer;
import android.os.Handler;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.view.View;
Expand Down Expand Up @@ -75,6 +77,10 @@ class VectorMessagesAdapterMediasHelper {
private final int mNotSentMessageTextColor;
private final int mDefaultMessageTextColor;

private final Handler handler = new Handler();
private HashMap<String, ImageView> mPlayImageViews = new HashMap<>();
private HashMap<String, MediaPlayer> mMediaPlayers;

VectorMessagesAdapterMediasHelper(Context context,
MXSession session,
int maxImageWidth,
Expand All @@ -96,8 +102,9 @@ class VectorMessagesAdapterMediasHelper {
*
* @param listener teh events listener
*/
void setVectorMessagesAdapterActionsListener(IMessagesAdapterActionsListener listener) {
void setVectorMessagesAdapterActionsListener(IMessagesAdapterActionsListener listener, HashMap<String, MediaPlayer> mediaPlayers) {
mVectorMessagesAdapterEventsListener = listener;
mMediaPlayers = mediaPlayers;
}

/**
Expand Down Expand Up @@ -180,6 +187,71 @@ public void onUploadComplete(final String uploadId, final String contentUri) {
refreshUploadViews(event, uploadStats, uploadProgressLayout);
}

void managePlayback(final View convertView, final Event event, final int type, final String mediaUrl) {
View playbackLayout = convertView.findViewById(R.id.content_media_playback_layout);
playbackLayout.setTag(mediaUrl);
final View playButton = playbackLayout.findViewById(R.id.media_playback);

if (null == playButton) return;

playButton.setTag(event);
playButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if ((event == playButton.getTag()) && (null != mVectorMessagesAdapterEventsListener)) {
ImageView imageView = playButton.findViewById(R.id.media_play_icon);
if ((null != imageView.getTag()) && (imageView.getTag().equals("playing"))) {
mVectorMessagesAdapterEventsListener.onEventAction(event, "", R.id.ic_action_pause_audio);
imageView.setImageResource(R.drawable.ic_baseline_play_arrow_24px);
imageView.setTag("paused");
} else {
mVectorMessagesAdapterEventsListener.onEventAction(event, "", R.id.ic_action_play_audio);
imageView.setTag("playing");
if (!mPlayImageViews.containsKey(mediaUrl)) {
mPlayImageViews.put(mediaUrl, imageView);
}
refreshPlayImageViews();
imageView.setImageResource(R.drawable.ic_baseline_pause_24px);
final ProgressBar progressBar = playbackLayout.findViewById(R.id.media_progress_view);
refreshPlaybackProgress(progressBar, mediaUrl);
}
}
}
});
}

void refreshPlayImageViews() {
for (ImageView iv : mPlayImageViews.values()) {
iv.setImageResource(R.drawable.ic_baseline_play_arrow_24px);
}
}

void refreshPlaybackProgress(ProgressBar progressBar, String mediaUrl) {
handler.postDelayed(new Runnable() {
@Override
public void run() {
if (null == mMediaPlayers) {
return;
}
try {
MediaPlayer mediaPlayer = mMediaPlayers.get(mediaUrl);

if (mediaPlayer == null || mediaUrl == null)
return;

progressBar.setProgress((int) ((float) mediaPlayer.getCurrentPosition() / mediaPlayer.getDuration() * progressBar.getMax()));
if (mediaPlayer.isPlaying()) {
refreshPlaybackProgress(progressBar, mediaUrl);
} else {
mPlayImageViews.get(mediaUrl).setImageResource(R.drawable.ic_baseline_play_arrow_24px);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}, 1000);
}

// the image / video bitmaps are set to null if the matching URL is not the same
// to avoid flickering
private Map<String, String> mUrlByBitmapIndex = new HashMap<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,13 @@

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
Expand All @@ -30,6 +35,7 @@
import android.support.v4.content.FileProvider;
import android.support.v7.app.AlertDialog;
import android.text.TextUtils;
import android.util.Base64;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
Expand Down Expand Up @@ -69,7 +75,10 @@
import org.matrix.androidsdk.rest.model.message.Message;
import org.matrix.androidsdk.rest.model.message.VideoMessage;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
Expand Down Expand Up @@ -109,8 +118,22 @@ public class VectorMessageListFragment extends MatrixMessageListFragment<VectorM
private String mPendingFilename;
private EncryptedFileInfo mPendingEncryptedFileInfo;

private IntentFilter mBecomingNoisyIntentFilter = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
private BroadcastReceiver mBecomingNoisyReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intent.getAction())) {
for (MediaPlayer mp : mMediaPlayers.values()) {
mp.pause();
}
}
}
};

private static int VERIF_REQ_CODE = 12;

private HashMap<String, MediaPlayer> mMediaPlayers;

public interface VectorMessageListFragmentListener {
/**
* Display a spinner to warn the user that a back pagination is in progress.
Expand Down Expand Up @@ -216,6 +239,8 @@ public void onItemClick(AdapterView<?> parent, View view, int position, long id)
}
});

mMediaPlayers = new HashMap<>();

v.setBackgroundColor(ThemeUtils.INSTANCE.getColor(getActivity(), android.R.attr.colorBackground));

return v;
Expand Down Expand Up @@ -247,7 +272,11 @@ protected String getMatrixMessagesFragmentTag() {
public void onPause() {
super.onPause();

mAdapter.setVectorMessagesAdapterActionsListener(null);
for (MediaPlayer mediaPlayer : mMediaPlayers.values()) {
mediaPlayer.pause();
}
getContext().unregisterReceiver(mBecomingNoisyReceiver);
mAdapter.setVectorMessagesAdapterActionsListener(null, mMediaPlayers);
mAdapter.onPause();

mVectorImageGetter.setListener(null);
Expand All @@ -258,7 +287,8 @@ public void onPause() {
public void onResume() {
super.onResume();

mAdapter.setVectorMessagesAdapterActionsListener(this);
getContext().registerReceiver(mBecomingNoisyReceiver, mBecomingNoisyIntentFilter);
mAdapter.setVectorMessagesAdapterActionsListener(this, mMediaPlayers);

mVectorImageGetter.setListener(new VectorImageGetter.OnImageDownloadListener() {
@Override
Expand Down Expand Up @@ -751,6 +781,20 @@ public void onDismiss(DialogInterface dialog) {
}
})
.show();
} else if (action == R.id.ic_action_play_audio) {
Message message = JsonUtils.toMessage(event.getContent());
FileMessage fileMessage = JsonUtils.toFileMessage(event.getContent());

if (null != fileMessage.getUrl()) {
onMediaAction(ACTION_VECTOR_OPEN, fileMessage.getUrl(), fileMessage.getMimeType(), fileMessage.body, fileMessage.file);
}
} else if (action == R.id.ic_action_pause_audio) {
Message message = JsonUtils.toMessage(event.getContent());
FileMessage fileMessage = JsonUtils.toFileMessage(event.getContent());

if (null != fileMessage.getUrl() && mMediaPlayers.containsKey(fileMessage.getUrl())) {
mMediaPlayers.get(fileMessage.getUrl()).pause();
}
}
}

Expand Down Expand Up @@ -893,7 +937,37 @@ public void onSuccess(File file) {
return;
}

if (menuAction == ACTION_VECTOR_SAVE || menuAction == ACTION_VECTOR_OPEN) {
if (menuAction == ACTION_VECTOR_OPEN && mediaMimeType.startsWith("audio/")) {
Log.e(LOG_TAG, "Using Media player " + file.getAbsolutePath());

for (MediaPlayer mp : mMediaPlayers.values()) {
mp.pause();
}

MediaPlayer mediaPlayer;
if (!mMediaPlayers.containsKey(mediaUrl)) {
mediaPlayer = new MediaPlayer();
mMediaPlayers.put(mediaUrl, mediaPlayer);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
int size = (int) file.length();
byte[] callData = new byte[size];
BufferedInputStream buf = new BufferedInputStream(new FileInputStream(file));
buf.read(callData, 0, callData.length);
buf.close();
String base64EncodedString = Base64.encodeToString(callData, Base64.DEFAULT);

String url = "data:audio/amr;base64," + base64EncodedString;
mediaPlayer.setDataSource(url);
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
} else {
mediaPlayer = mMediaPlayers.get(mediaUrl);
}
mediaPlayer.start();
} else if (menuAction == ACTION_VECTOR_SAVE || menuAction == ACTION_VECTOR_OPEN) {
if (PermissionsToolsKt.checkPermissions(PermissionsToolsKt.PERMISSIONS_FOR_WRITING_FILES,
VectorMessageListFragment.this, PermissionsToolsKt.PERMISSION_REQUEST_CODE)) {
CommonActivityUtils.saveMediaIntoDownloads(getActivity(), file, trimmedFileName, mediaMimeType, new SimpleApiCallback<String>() {
Expand Down Expand Up @@ -1151,7 +1225,7 @@ public void onContentClick(int position) {

getActivity().startActivity(viewImageIntent);
}
} else if (Message.MSGTYPE_FILE.equals(message.msgtype) || Message.MSGTYPE_AUDIO.equals(message.msgtype)) {
} else if (Message.MSGTYPE_FILE.equals(message.msgtype)) {
FileMessage fileMessage = JsonUtils.toFileMessage(event.getContent());

if (null != fileMessage.getUrl()) {
Expand Down
9 changes: 9 additions & 0 deletions vector/src/main/res/drawable/ic_baseline_pause_24px.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M6,19h4L10,5L6,5v14zM14,5v14h4L18,5h-4z"/>
</vector>
9 changes: 9 additions & 0 deletions vector/src/main/res/drawable/ic_baseline_play_arrow_24px.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M8,5v14l11,-7z"/>
</vector>
10 changes: 10 additions & 0 deletions vector/src/main/res/layout/adapter_item_vector_message_file.xml
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,16 @@

</RelativeLayout>

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">

<include
android:id="@+id/content_media_playback_layout"
layout="@layout/media_playback_control" />

</RelativeLayout>

</LinearLayout>

</LinearLayout>
Expand Down
50 changes: 50 additions & 0 deletions vector/src/main/res/layout/media_playback_control.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="false"
android:orientation="horizontal">

<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">

<TextView
android:id="@+id/media_progress_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:textSize="10sp"
tools:text="Information" />

<ProgressBar
android:id="@+id/media_progress_view"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_gravity="center_vertical"
android:max="100"
android:progress="0"
tools:progress="30" />

</LinearLayout>

<FrameLayout
android:id="@+id/media_playback"
android:layout_width="40dp"
android:layout_height="match_parent">

<ImageView
android:id="@+id/media_play_icon"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="bottom|end"
android:src="@drawable/ic_baseline_play_arrow_24px"
android:tint="?attr/vctr_settings_icon_tint_color" />

</FrameLayout>

</LinearLayout>
Loading

0 comments on commit c0807ab

Please sign in to comment.