mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-21 15:05:19 +00:00
Migrate exoplayer to media3
This commit is contained in:
parent
fb937ee292
commit
d82c5b6a1b
@ -269,8 +269,8 @@ dependencies {
|
||||
exclude group: 'com.google.firebase', module: 'firebase-measurement-connector'
|
||||
}
|
||||
if (project.hasProperty('huawei')) huaweiImplementation 'com.huawei.hms:push:6.7.0.300'
|
||||
implementation 'com.google.android.exoplayer:exoplayer-core:2.9.1'
|
||||
implementation 'com.google.android.exoplayer:exoplayer-ui:2.9.1'
|
||||
implementation 'androidx.media3:media3-exoplayer:1.4.0'
|
||||
implementation 'androidx.media3:media3-ui:1.4.0'
|
||||
implementation 'org.conscrypt:conscrypt-android:2.5.2'
|
||||
implementation 'org.signal:aesgcmprovider:0.0.3'
|
||||
implementation 'io.github.webrtc-sdk:android:125.6422.04'
|
||||
|
@ -6,49 +6,35 @@ import android.hardware.SensorEvent;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorManager;
|
||||
import android.media.AudioManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.PowerManager;
|
||||
import android.os.PowerManager.WakeLock;
|
||||
import android.util.Pair;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import android.util.Pair;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.DefaultLoadControl;
|
||||
import com.google.android.exoplayer2.DefaultRenderersFactory;
|
||||
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||
import com.google.android.exoplayer2.ExoPlayerFactory;
|
||||
import com.google.android.exoplayer2.LoadControl;
|
||||
import com.google.android.exoplayer2.PlaybackParameters;
|
||||
import com.google.android.exoplayer2.Player;
|
||||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
||||
import com.google.android.exoplayer2.audio.AudioAttributes;
|
||||
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
|
||||
import com.google.android.exoplayer2.source.ExtractorMediaSource;
|
||||
import com.google.android.exoplayer2.source.MediaSource;
|
||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
|
||||
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
|
||||
import androidx.annotation.OptIn;
|
||||
import androidx.media3.common.AudioAttributes;
|
||||
import androidx.media3.common.C;
|
||||
import androidx.media3.common.MediaItem;
|
||||
import androidx.media3.common.PlaybackException;
|
||||
import androidx.media3.common.PlaybackParameters;
|
||||
import androidx.media3.common.Player;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import androidx.media3.exoplayer.ExoPlayer;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.thoughtcrime.securesms.attachments.AttachmentServer;
|
||||
import org.session.libsignal.utilities.Log;
|
||||
import org.thoughtcrime.securesms.mms.AudioSlide;
|
||||
import org.session.libsession.utilities.ServiceUtil;
|
||||
|
||||
import org.session.libsession.utilities.Util;
|
||||
|
||||
import org.session.libsignal.utilities.Log;
|
||||
import org.session.libsignal.utilities.guava.Optional;
|
||||
import org.thoughtcrime.securesms.attachments.AttachmentServer;
|
||||
import org.thoughtcrime.securesms.mms.AudioSlide;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import network.loki.messenger.BuildConfig;
|
||||
import network.loki.messenger.R;
|
||||
|
||||
public class AudioSlidePlayer implements SensorEventListener {
|
||||
|
||||
private static final String TAG = AudioSlidePlayer.class.getSimpleName();
|
||||
@ -64,7 +50,7 @@ public class AudioSlidePlayer implements SensorEventListener {
|
||||
private final @Nullable WakeLock wakeLock;
|
||||
|
||||
private @NonNull WeakReference<Listener> listener;
|
||||
private @Nullable SimpleExoPlayer mediaPlayer;
|
||||
private @Nullable ExoPlayer mediaPlayer;
|
||||
private @Nullable AttachmentServer audioAttachmentServer;
|
||||
private long startTime;
|
||||
|
||||
@ -97,40 +83,38 @@ public class AudioSlidePlayer implements SensorEventListener {
|
||||
this.sensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
|
||||
this.proximitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
this.wakeLock = ServiceUtil.getPowerManager(context).newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, TAG);
|
||||
} else {
|
||||
this.wakeLock = null;
|
||||
}
|
||||
this.wakeLock = ServiceUtil.getPowerManager(context).newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, TAG);
|
||||
}
|
||||
|
||||
public void play(final double progress) throws IOException {
|
||||
play(progress, false);
|
||||
}
|
||||
|
||||
@OptIn(markerClass = UnstableApi.class)
|
||||
private void play(final double progress, boolean earpiece) throws IOException {
|
||||
if (this.mediaPlayer != null) { stop(); }
|
||||
|
||||
LoadControl loadControl = new DefaultLoadControl.Builder().setBufferDurationsMs(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE).createDefaultLoadControl();
|
||||
this.mediaPlayer = ExoPlayerFactory.newSimpleInstance(context, new DefaultRenderersFactory(context), new DefaultTrackSelector(), loadControl);
|
||||
this.mediaPlayer = new ExoPlayer.Builder(context).build();
|
||||
this.audioAttachmentServer = new AttachmentServer(context, slide.asAttachment());
|
||||
this.startTime = System.currentTimeMillis();
|
||||
|
||||
audioAttachmentServer.start();
|
||||
|
||||
mediaPlayer.prepare(createMediaSource(audioAttachmentServer.getUri()));
|
||||
mediaPlayer.setPlayWhenReady(true);
|
||||
MediaItem mediaItem = MediaItem.fromUri(audioAttachmentServer.getUri());
|
||||
mediaPlayer.setMediaItem(mediaItem);
|
||||
|
||||
mediaPlayer.setAudioAttributes(new AudioAttributes.Builder()
|
||||
.setContentType(earpiece ? C.CONTENT_TYPE_SPEECH : C.CONTENT_TYPE_MUSIC)
|
||||
.setContentType(earpiece ? C.AUDIO_CONTENT_TYPE_SPEECH : C.AUDIO_CONTENT_TYPE_MUSIC)
|
||||
.setUsage(earpiece ? C.USAGE_VOICE_COMMUNICATION : C.USAGE_MEDIA)
|
||||
.build());
|
||||
mediaPlayer.addListener(new Player.EventListener() {
|
||||
.build(),
|
||||
!earpiece);
|
||||
mediaPlayer.addListener(new Player.Listener() {
|
||||
|
||||
boolean started = false;
|
||||
|
||||
@Override
|
||||
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
|
||||
Log.d(TAG, "onPlayerStateChanged(" + playWhenReady + ", " + playbackState + ")");
|
||||
public void onPlaybackStateChanged(int playbackState) {
|
||||
Log.d(TAG, "onPlaybackStateChanged(" + playbackState + ")");
|
||||
switch (playbackState) {
|
||||
case Player.STATE_READY:
|
||||
Log.i(TAG, "onPrepared() " + mediaPlayer.getBufferedPercentage() + "% buffered");
|
||||
@ -174,9 +158,7 @@ public class AudioSlidePlayer implements SensorEventListener {
|
||||
sensorManager.unregisterListener(AudioSlidePlayer.this);
|
||||
|
||||
if (wakeLock != null && wakeLock.isHeld()) {
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
wakeLock.release(PowerManager.RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY);
|
||||
}
|
||||
wakeLock.release(PowerManager.RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY);
|
||||
}
|
||||
}
|
||||
|
||||
@ -186,8 +168,9 @@ public class AudioSlidePlayer implements SensorEventListener {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onPlayerError(ExoPlaybackException error) {
|
||||
public void onPlayerError(PlaybackException error) {
|
||||
Log.w(TAG, "MediaPlayer Error: " + error);
|
||||
|
||||
synchronized (AudioSlidePlayer.this) {
|
||||
@ -201,9 +184,7 @@ public class AudioSlidePlayer implements SensorEventListener {
|
||||
sensorManager.unregisterListener(AudioSlidePlayer.this);
|
||||
|
||||
if (wakeLock != null && wakeLock.isHeld()) {
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
wakeLock.release(PowerManager.RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY);
|
||||
}
|
||||
wakeLock.release(PowerManager.RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY);
|
||||
}
|
||||
}
|
||||
|
||||
@ -211,12 +192,9 @@ public class AudioSlidePlayer implements SensorEventListener {
|
||||
progressEventHandler.removeMessages(0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private MediaSource createMediaSource(@NonNull Uri uri) {
|
||||
return new ExtractorMediaSource.Factory(new DefaultDataSourceFactory(context, BuildConfig.USER_AGENT))
|
||||
.setExtractorsFactory(new DefaultExtractorsFactory().setConstantBitrateSeekingEnabled(true))
|
||||
.createMediaSource(uri);
|
||||
mediaPlayer.prepare();
|
||||
mediaPlayer.setPlayWhenReady(true);
|
||||
}
|
||||
|
||||
public synchronized void stop() {
|
||||
@ -348,14 +326,18 @@ public class AudioSlidePlayer implements SensorEventListener {
|
||||
|
||||
int streamType;
|
||||
|
||||
if (event.values[0] < 5f && event.values[0] != proximitySensor.getMaximumRange()) {
|
||||
streamType = AudioManager.STREAM_VOICE_CALL;
|
||||
if (
|
||||
proximitySensor != null &&
|
||||
event.values[0] < 5f &&
|
||||
event.values[0] != proximitySensor.getMaximumRange()
|
||||
) {
|
||||
streamType = C.AUDIO_CONTENT_TYPE_SPEECH;
|
||||
} else {
|
||||
streamType = AudioManager.STREAM_MUSIC;
|
||||
streamType = C.AUDIO_CONTENT_TYPE_MUSIC;
|
||||
}
|
||||
|
||||
if (streamType == AudioManager.STREAM_VOICE_CALL &&
|
||||
mediaPlayer.getAudioStreamType() != streamType &&
|
||||
if (streamType == C.AUDIO_CONTENT_TYPE_SPEECH &&
|
||||
mediaPlayer.getAudioAttributes().contentType != streamType &&
|
||||
!audioManager.isWiredHeadsetOn())
|
||||
{
|
||||
double position = mediaPlayer.getCurrentPosition();
|
||||
@ -369,11 +351,11 @@ public class AudioSlidePlayer implements SensorEventListener {
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, e);
|
||||
}
|
||||
} else if (streamType == AudioManager.STREAM_MUSIC &&
|
||||
mediaPlayer.getAudioStreamType() != streamType &&
|
||||
} else if (streamType == C.AUDIO_CONTENT_TYPE_MUSIC &&
|
||||
mediaPlayer.getAudioAttributes().contentType != streamType &&
|
||||
System.currentTimeMillis() - startTime > 500)
|
||||
{
|
||||
if (wakeLock != null) wakeLock.release();
|
||||
if (wakeLock != null && wakeLock.isHeld()) wakeLock.release();
|
||||
stop();
|
||||
notifyOnStop();
|
||||
}
|
||||
@ -411,7 +393,7 @@ public class AudioSlidePlayer implements SensorEventListener {
|
||||
sendEmptyMessageDelayed(0, 50);
|
||||
}
|
||||
|
||||
private boolean isPlayerActive(@NonNull SimpleExoPlayer player) {
|
||||
private boolean isPlayerActive(@NonNull ExoPlayer player) {
|
||||
return player.getPlaybackState() == Player.STATE_READY || player.getPlaybackState() == Player.STATE_BUFFERING;
|
||||
}
|
||||
}
|
||||
|
@ -536,7 +536,7 @@ open class Storage(
|
||||
}
|
||||
|
||||
private fun updateConvoVolatile(convos: ConversationVolatileConfig, messageTimestamp: Long) {
|
||||
val extracted = convos.all()
|
||||
val extracted = convos.all().filterNotNull()
|
||||
for (conversation in extracted) {
|
||||
val threadId = when (conversation) {
|
||||
is Conversation.OneToOne -> getThreadIdFor(conversation.accountId, null, null, createThread = false)
|
||||
|
@ -4,7 +4,10 @@ import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.OptIn;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@ -16,6 +19,7 @@ import org.thoughtcrime.securesms.video.VideoPlayer;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@OptIn(markerClass = UnstableApi.class)
|
||||
public class MediaSendVideoFragment extends Fragment implements MediaSendPageFragment {
|
||||
|
||||
private static final String TAG = MediaSendVideoFragment.class.getSimpleName();
|
||||
|
@ -18,56 +18,46 @@ package org.thoughtcrime.securesms.video;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.MediaController;
|
||||
import android.widget.Toast;
|
||||
import android.widget.VideoView;
|
||||
|
||||
import com.google.android.exoplayer2.DefaultLoadControl;
|
||||
import com.google.android.exoplayer2.ExoPlayerFactory;
|
||||
import com.google.android.exoplayer2.LoadControl;
|
||||
import com.google.android.exoplayer2.Player;
|
||||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
||||
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
|
||||
import com.google.android.exoplayer2.extractor.ExtractorsFactory;
|
||||
import com.google.android.exoplayer2.source.ExtractorMediaSource;
|
||||
import com.google.android.exoplayer2.source.MediaSource;
|
||||
import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelector;
|
||||
import com.google.android.exoplayer2.ui.PlayerControlView;
|
||||
import com.google.android.exoplayer2.ui.PlayerView;
|
||||
import com.google.android.exoplayer2.upstream.BandwidthMeter;
|
||||
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
|
||||
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.thoughtcrime.securesms.attachments.AttachmentServer;
|
||||
import androidx.media3.common.MediaItem;
|
||||
import androidx.media3.common.Player;
|
||||
import androidx.media3.common.AudioAttributes;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import androidx.media3.exoplayer.ExoPlayer;
|
||||
import androidx.media3.ui.LegacyPlayerControlView;
|
||||
import androidx.media3.ui.PlayerView;
|
||||
|
||||
|
||||
import org.session.libsession.utilities.ViewUtil;
|
||||
import org.session.libsignal.utilities.Log;
|
||||
import org.thoughtcrime.securesms.attachments.AttachmentServer;
|
||||
import org.thoughtcrime.securesms.mms.PartAuthority;
|
||||
import org.thoughtcrime.securesms.mms.VideoSlide;
|
||||
import org.session.libsession.utilities.ViewUtil;
|
||||
import org.thoughtcrime.securesms.video.exo.AttachmentDataSourceFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import network.loki.messenger.R;
|
||||
|
||||
@UnstableApi
|
||||
public class VideoPlayer extends FrameLayout {
|
||||
|
||||
private static final String TAG = VideoPlayer.class.getSimpleName();
|
||||
|
||||
@Nullable private final VideoView videoView;
|
||||
@Nullable private final PlayerView exoView;
|
||||
@Nullable private final PlayerView exoView;
|
||||
|
||||
@Nullable private SimpleExoPlayer exoPlayer;
|
||||
@Nullable private PlayerControlView exoControls;
|
||||
@Nullable private ExoPlayer exoPlayer;
|
||||
@Nullable private LegacyPlayerControlView exoControls;
|
||||
@Nullable private AttachmentServer attachmentServer;
|
||||
@Nullable private Window window;
|
||||
|
||||
@ -84,23 +74,16 @@ public class VideoPlayer extends FrameLayout {
|
||||
|
||||
inflate(context, R.layout.video_player, this);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 16) {
|
||||
this.exoView = ViewUtil.findById(this, R.id.video_view);
|
||||
this.videoView = null;
|
||||
this.exoControls = new PlayerControlView(getContext());
|
||||
this.exoControls.setShowTimeoutMs(-1);
|
||||
} else {
|
||||
this.videoView = ViewUtil.findById(this, R.id.video_view);
|
||||
this.exoView = null;
|
||||
initializeVideoViewControls(videoView);
|
||||
}
|
||||
this.exoView = ViewUtil.findById(this, R.id.video_view);
|
||||
this.videoView = null;
|
||||
this.exoControls = new LegacyPlayerControlView(getContext());
|
||||
this.exoControls.setShowTimeoutMs(-1);
|
||||
}
|
||||
|
||||
public void setVideoSource(@NonNull VideoSlide videoSource, boolean autoplay)
|
||||
throws IOException
|
||||
{
|
||||
if (Build.VERSION.SDK_INT >= 16) setExoViewSource(videoSource, autoplay);
|
||||
else setVideoViewSource(videoSource, autoplay);
|
||||
setExoViewSource(videoSource, autoplay);
|
||||
}
|
||||
|
||||
public void pause() {
|
||||
@ -141,25 +124,20 @@ public class VideoPlayer extends FrameLayout {
|
||||
private void setExoViewSource(@NonNull VideoSlide videoSource, boolean autoplay)
|
||||
throws IOException
|
||||
{
|
||||
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
|
||||
TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
|
||||
TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
|
||||
LoadControl loadControl = new DefaultLoadControl();
|
||||
|
||||
exoPlayer = ExoPlayerFactory.newSimpleInstance(getContext(), trackSelector, loadControl);
|
||||
exoPlayer = new ExoPlayer.Builder(getContext()).build();
|
||||
exoPlayer.addListener(new ExoPlayerListener(window));
|
||||
exoPlayer.setAudioAttributes(AudioAttributes.DEFAULT, true);
|
||||
//noinspection ConstantConditions
|
||||
exoView.setPlayer(exoPlayer);
|
||||
//noinspection ConstantConditions
|
||||
exoControls.setPlayer(exoPlayer);
|
||||
|
||||
DefaultDataSourceFactory defaultDataSourceFactory = new DefaultDataSourceFactory(getContext(), "GenericUserAgent", null);
|
||||
AttachmentDataSourceFactory attachmentDataSourceFactory = new AttachmentDataSourceFactory(getContext(), defaultDataSourceFactory, null);
|
||||
ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
|
||||
if(videoSource.getUri() != null){
|
||||
MediaItem mediaItem = MediaItem.fromUri(videoSource.getUri());
|
||||
exoPlayer.setMediaItem(mediaItem);
|
||||
}
|
||||
|
||||
MediaSource mediaSource = new ExtractorMediaSource(videoSource.getUri(), attachmentDataSourceFactory, extractorsFactory, null, null);
|
||||
|
||||
exoPlayer.prepare(mediaSource);
|
||||
exoPlayer.prepare();
|
||||
exoPlayer.setPlayWhenReady(autoplay);
|
||||
}
|
||||
|
||||
@ -189,15 +167,7 @@ public class VideoPlayer extends FrameLayout {
|
||||
if (autoplay) this.videoView.start();
|
||||
}
|
||||
|
||||
private void initializeVideoViewControls(@NonNull VideoView videoView) {
|
||||
MediaController mediaController = new MediaController(getContext());
|
||||
mediaController.setAnchorView(videoView);
|
||||
mediaController.setMediaPlayer(videoView);
|
||||
|
||||
videoView.setMediaController(mediaController);
|
||||
}
|
||||
|
||||
private static class ExoPlayerListener extends Player.DefaultEventListener {
|
||||
private static class ExoPlayerListener implements Player.Listener {
|
||||
private final Window window;
|
||||
|
||||
ExoPlayerListener(Window window) {
|
||||
|
@ -1,61 +0,0 @@
|
||||
package org.thoughtcrime.securesms.video.exo;
|
||||
|
||||
|
||||
import android.net.Uri;
|
||||
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||
import com.google.android.exoplayer2.upstream.DefaultDataSource;
|
||||
import com.google.android.exoplayer2.upstream.TransferListener;
|
||||
|
||||
import org.thoughtcrime.securesms.mms.PartAuthority;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class AttachmentDataSource implements DataSource {
|
||||
|
||||
private final DefaultDataSource defaultDataSource;
|
||||
private final PartDataSource partDataSource;
|
||||
|
||||
private DataSource dataSource;
|
||||
|
||||
public AttachmentDataSource(DefaultDataSource defaultDataSource, PartDataSource partDataSource) {
|
||||
this.defaultDataSource = defaultDataSource;
|
||||
this.partDataSource = partDataSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTransferListener(TransferListener transferListener) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long open(DataSpec dataSpec) throws IOException {
|
||||
if (PartAuthority.isLocalUri(dataSpec.uri)) dataSource = partDataSource;
|
||||
else dataSource = defaultDataSource;
|
||||
|
||||
return dataSource.open(dataSpec);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] buffer, int offset, int readLength) throws IOException {
|
||||
return dataSource.read(buffer, offset, readLength);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri getUri() {
|
||||
return dataSource.getUri();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, List<String>> getResponseHeaders() {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
dataSource.close();
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
package org.thoughtcrime.securesms.video.exo;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
|
||||
import com.google.android.exoplayer2.upstream.TransferListener;
|
||||
|
||||
public class AttachmentDataSourceFactory implements DataSource.Factory {
|
||||
|
||||
private final Context context;
|
||||
|
||||
private final DefaultDataSourceFactory defaultDataSourceFactory;
|
||||
private final TransferListener listener;
|
||||
|
||||
public AttachmentDataSourceFactory(@NonNull Context context,
|
||||
@NonNull DefaultDataSourceFactory defaultDataSourceFactory,
|
||||
@Nullable TransferListener listener)
|
||||
{
|
||||
this.context = context;
|
||||
this.defaultDataSourceFactory = defaultDataSourceFactory;
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AttachmentDataSource createDataSource() {
|
||||
return new AttachmentDataSource(defaultDataSourceFactory.createDataSource(),
|
||||
new PartDataSource(context, listener));
|
||||
}
|
||||
}
|
@ -1,89 +0,0 @@
|
||||
package org.thoughtcrime.securesms.video.exo;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||
import com.google.android.exoplayer2.upstream.TransferListener;
|
||||
|
||||
import org.session.libsession.messaging.sending_receiving.attachments.Attachment;
|
||||
import org.thoughtcrime.securesms.database.AttachmentDatabase;
|
||||
import org.thoughtcrime.securesms.dependencies.DatabaseComponent;
|
||||
import org.thoughtcrime.securesms.mms.PartUriParser;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class PartDataSource implements DataSource {
|
||||
|
||||
private final @NonNull Context context;
|
||||
private final @Nullable TransferListener listener;
|
||||
|
||||
private Uri uri;
|
||||
private InputStream inputSteam;
|
||||
|
||||
PartDataSource(@NonNull Context context, @Nullable TransferListener listener) {
|
||||
this.context = context.getApplicationContext();
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTransferListener(TransferListener transferListener) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long open(DataSpec dataSpec) throws IOException {
|
||||
this.uri = dataSpec.uri;
|
||||
|
||||
AttachmentDatabase attachmentDatabase = DatabaseComponent.get(context).attachmentDatabase();
|
||||
PartUriParser partUri = new PartUriParser(uri);
|
||||
Attachment attachment = attachmentDatabase.getAttachment(partUri.getPartId());
|
||||
|
||||
if (attachment == null) throw new IOException("Attachment not found");
|
||||
|
||||
this.inputSteam = attachmentDatabase.getAttachmentStream(partUri.getPartId(), dataSpec.position);
|
||||
|
||||
if (listener != null) {
|
||||
listener.onTransferStart(this, dataSpec, false);
|
||||
}
|
||||
|
||||
if (attachment.getSize() - dataSpec.position <= 0) throw new EOFException("No more data");
|
||||
|
||||
return attachment.getSize() - dataSpec.position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] buffer, int offset, int readLength) throws IOException {
|
||||
int read = inputSteam.read(buffer, offset, readLength);
|
||||
|
||||
if (read > 0 && listener != null) {
|
||||
listener.onBytesTransferred(this, null, false, read);
|
||||
}
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri getUri() {
|
||||
return uri;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, List<String>> getResponseHeaders() {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
inputSteam.close();
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.google.android.exoplayer2.ui.AspectRatioFrameLayout
|
||||
<androidx.media3.ui.AspectRatioFrameLayout
|
||||
android:id="@+id/exo_content_frame"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
@ -6,7 +6,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.google.android.exoplayer2.ui.PlayerView
|
||||
<androidx.media3.ui.PlayerView
|
||||
android:id="@+id/video_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
@ -341,22 +341,6 @@
|
||||
<attr name="labeledEditText_textLayout" format="reference" />
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="WaveformSeekBar">
|
||||
<attr name="progress" format="float"/>
|
||||
<attr name="bar_width" format="dimension"/>
|
||||
<attr name="bar_gap" format="dimension"/>
|
||||
<attr name="bar_min_height" format="dimension"/>
|
||||
<attr name="bar_corner_radius" format="dimension"/>
|
||||
<attr name="bar_background_color" format="color"/>
|
||||
<attr name="bar_progress_color" format="color"/>
|
||||
<!-- Corresponds to WaveformSeekBar.WaveGravity enum. -->
|
||||
<attr name="bar_gravity" format="enum">
|
||||
<enum name="top" value="1" />
|
||||
<enum name="center" value="2" />
|
||||
<enum name="bottom" value="3" />
|
||||
</attr>
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="KeyboardPageSearchView">
|
||||
<attr name="show_always" format="boolean" />
|
||||
<attr name="search_bar_tint" format="color|reference" />
|
||||
|
@ -162,7 +162,7 @@ class ConversationVolatileConfig(pointer: Long): ConfigBase(pointer) {
|
||||
external fun allOneToOnes(): List<Conversation.OneToOne>
|
||||
external fun allCommunities(): List<Conversation.Community>
|
||||
external fun allLegacyClosedGroups(): List<Conversation.LegacyGroup>
|
||||
external fun all(): List<Conversation>
|
||||
external fun all(): List<Conversation?>
|
||||
|
||||
}
|
||||
|
||||
|
@ -270,22 +270,6 @@
|
||||
<attr name="labeledEditText_textLayout" format="reference" />
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="WaveformSeekBar">
|
||||
<attr name="progress" format="float"/>
|
||||
<attr name="bar_width" format="dimension"/>
|
||||
<attr name="bar_gap" format="dimension"/>
|
||||
<attr name="bar_min_height" format="dimension"/>
|
||||
<attr name="bar_corner_radius" format="dimension"/>
|
||||
<attr name="bar_background_color" format="color"/>
|
||||
<attr name="bar_progress_color" format="color"/>
|
||||
<!-- Corresponds to WaveformSeekBar.WaveGravity enum. -->
|
||||
<attr name="bar_gravity" format="enum">
|
||||
<enum name="top" value="1" />
|
||||
<enum name="center" value="2" />
|
||||
<enum name="bottom" value="3" />
|
||||
</attr>
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="KeyboardPageSearchView">
|
||||
<attr name="show_always" format="boolean" />
|
||||
<attr name="search_bar_tint" format="color|reference" />
|
||||
|
Loading…
Reference in New Issue
Block a user