Auto play video when ended

This commit is contained in:
Thomas 2020-10-31 10:37:17 +01:00
parent 4f909417f1
commit ed9e79496a
5 changed files with 188 additions and 3 deletions

View File

@ -68,8 +68,10 @@ import androidx.recyclerview.widget.RecyclerView;
import com.github.vkay94.dtpv.youtube.YouTubeOverlay;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector;
import com.google.android.exoplayer2.source.MediaSource;
@ -136,9 +138,10 @@ import static app.fedilab.fedilabtube.client.RetrofitPeertubeAPI.ActionType.REPO
import static app.fedilab.fedilabtube.helper.Helper.getAttColor;
import static app.fedilab.fedilabtube.helper.Helper.getLiveInstance;
import static app.fedilab.fedilabtube.helper.Helper.isLoggedIn;
import static com.google.android.exoplayer2.Player.MEDIA_ITEM_TRANSITION_REASON_AUTO;
public class PeertubeActivity extends AppCompatActivity implements CommentListAdapter.AllCommentRemoved {
public class PeertubeActivity extends AppCompatActivity implements CommentListAdapter.AllCommentRemoved, Player.EventListener {
public static String video_id;
private String peertubeInstance, videoUuid;
@ -165,6 +168,8 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
private BroadcastReceiver mPowerKeyReceiver = null;
private boolean isPlayInMinimized;
private Intent urlIntent;
public static List<String> playedVideos = new ArrayList<>();
private VideoData.Video nextVideo;
public static void hideKeyboard(Activity activity) {
if (activity != null && activity.getWindow() != null) {
@ -572,6 +577,35 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
}
public void manageNextVideos(APIResponse apiResponse) {
if (apiResponse == null || apiResponse.getError() != null || apiResponse.getPeertubes() == null || apiResponse.getPeertubes().size() == 0) {
return;
}
List<VideoData.Video> suggestedVideos = apiResponse.getPeertubes();
for(VideoData.Video video: suggestedVideos) {
if(!playedVideos.contains(video.getId())){
TimelineVM feedsViewModel = new ViewModelProvider(PeertubeActivity.this).get(TimelineVM.class);
feedsViewModel.getVideo(null, suggestedVideos.get(0).getUuid(), false).observe(PeertubeActivity.this, this::nextVideoDetails);
return;
}
}
}
@SuppressLint("ClickableViewAccessibility")
public void nextVideoDetails(APIResponse apiResponse) {
if (apiResponse == null || (apiResponse.getError() != null) || apiResponse.getPeertubes() == null || apiResponse.getPeertubes().size() == 0) {
return;
}
int i = 0;
while (i < (apiResponse.getPeertubes().size()-1) && playedVideos.contains(apiResponse.getPeertubes().get(i).getId())) {
i++;
}
nextVideo = apiResponse.getPeertubes().get(i);
MediaItem mediaItem = new MediaItem.Builder().setUri(Uri.parse(nextVideo.getFileUrl(null, PeertubeActivity.this))).build();
player.addMediaItem(mediaItem);
}
@SuppressLint("ClickableViewAccessibility")
public void manageVIewVideo(APIResponse apiResponse) {
@ -588,6 +622,10 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
peertube = apiResponse.getPeertubes().get(0);
if( peertube.getTags() != null && peertube.getTags().size() > 0) {
SearchVM searchViewModel = new ViewModelProvider(PeertubeActivity.this).get(SearchVM.class);
searchViewModel.searchNextVideos(peertube.getTags()).observe(PeertubeActivity.this, this::manageNextVideos);
}
if (sepiaSearch) {
peertubeInstance = peertube.getAccount().getHost();
}
@ -711,6 +749,7 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
ProgressiveMediaSource videoSource;
player = new SimpleExoPlayer.Builder(PeertubeActivity.this).build();
player.addListener(this);
binding.mediaVideo.player(player);
binding.doubleTapPlayerView.setPlayer(player);
binding.loader.setVisibility(View.GONE);
@ -1273,6 +1312,8 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
}
player.setPlayWhenReady(true);
});
View exo_next = controlView.findViewById(R.id.exo_next);
exo_next.setOnClickListener(v -> playNextVideo());
}
private void initResolution() {
@ -1415,4 +1456,35 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
public void onAllCommentRemoved() {
binding.noActionText.setVisibility(View.VISIBLE);
}
private void playNextVideo() {
if( nextVideo != null) {
Intent intent = new Intent(PeertubeActivity.this, PeertubeActivity.class);
Bundle b = new Bundle();
b.putParcelable("video",nextVideo);
b.putString("video_id", nextVideo.getId());
b.putString("video_uuid", nextVideo.getUuid());
playedVideos.add(nextVideo.getId());
b.putBoolean("sepia_search", sepiaSearch);
intent.putExtras(b);
startActivity(intent);
}
}
@Override
public void onMediaItemTransition(MediaItem mediaItem, int reason) {
if (reason == MEDIA_ITEM_TRANSITION_REASON_AUTO){
player.removeMediaItems(0, player.getMediaItemCount());
playNextVideo();
}
}
@Override
public void onPlayerError(ExoPlaybackException error) {
}
}

View File

@ -172,7 +172,20 @@ public interface PeertubeService {
//Search
@GET("search/videos")
Call<VideoData> searchVideos(@Header("Authorization") String credentials, @Query("search") String search, @Query("start") String maxId, @Query("count") String count);
Call<VideoData> searchVideos(
@Header("Authorization") String credentials,
@Query("search") String search,
@Query("start") String maxId,
@Query("count") String count);
//Search
@GET("search/videos")
Call<VideoData> searchNextVideo(
@Header("Authorization") String credentials,
@Query("tagsOneOf") List<String> tagsOneOf,
@Query("start") String maxId,
@Query("count") String count);
//Get notifications
@GET("users/me/notifications")

View File

@ -702,6 +702,33 @@ public class RetrofitPeertubeAPI {
return apiResponse;
}
/**
* Retrieves next peertube videos *synchronously*
*
* @param tags List<String> search
* @return APIResponse
*/
public APIResponse searchNextVideos(List<String> tags) {
PeertubeService peertubeService = init();
Call<VideoData> searchVideosCall = peertubeService.searchNextVideo(getToken(), tags, "0" , "20");
APIResponse apiResponse = new APIResponse();
try {
Response<VideoData> response = searchVideosCall.execute();
if (response.isSuccessful() && response.body() != null) {
apiResponse.setPeertubes(response.body().data);
} else {
setError(apiResponse, response.code(), response.errorBody());
}
} catch (IOException e) {
Error error = new Error();
error.setError(_context.getString(R.string.toast_error));
apiResponse.setError(error);
e.printStackTrace();
}
return apiResponse;
}
/**
* Retrieves peertube search *synchronously*
*

View File

@ -1,10 +1,13 @@
package app.fedilab.fedilabtube.client.entities;
import android.os.Parcel;
import android.os.Parcelable;
import com.google.gson.annotations.SerializedName;
@SuppressWarnings({"unused", "RedundantSuppression"})
public class File {
public class File implements Parcelable {
@SerializedName("fileDownloadUrl")
private String fileDownloadUrl;
@ -96,4 +99,50 @@ public class File {
public void setTorrentUrl(String torrentUrl) {
this.torrentUrl = torrentUrl;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.fileDownloadUrl);
dest.writeString(this.fileUrl);
dest.writeInt(this.fps);
dest.writeString(this.magnetUri);
dest.writeString(this.metadataUrl);
dest.writeParcelable(this.resolutions, flags);
dest.writeLong(this.size);
dest.writeString(this.torrentDownloadUrl);
dest.writeString(this.torrentUrl);
}
public File() {
}
protected File(Parcel in) {
this.fileDownloadUrl = in.readString();
this.fileUrl = in.readString();
this.fps = in.readInt();
this.magnetUri = in.readString();
this.metadataUrl = in.readString();
this.resolutions = in.readParcelable(Item.class.getClassLoader());
this.size = in.readLong();
this.torrentDownloadUrl = in.readString();
this.torrentUrl = in.readString();
}
public static final Parcelable.Creator<File> CREATOR = new Parcelable.Creator<File>() {
@Override
public File createFromParcel(Parcel source) {
return new File(source);
}
@Override
public File[] newArray(int size) {
return new File[size];
}
};
}

View File

@ -24,6 +24,8 @@ import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import java.util.List;
import app.fedilab.fedilabtube.client.APIResponse;
import app.fedilab.fedilabtube.client.RetrofitPeertubeAPI;
@ -41,6 +43,12 @@ public class SearchVM extends AndroidViewModel {
return apiResponseMutableLiveData;
}
public LiveData<APIResponse> searchNextVideos(List<String> tags) {
apiResponseMutableLiveData = new MutableLiveData<>();
loadNextVideos(tags);
return apiResponseMutableLiveData;
}
private void loadVideos(String max_id, String query) {
Context _mContext = getApplication().getApplicationContext();
new Thread(() -> {
@ -55,4 +63,20 @@ public class SearchVM extends AndroidViewModel {
}
}).start();
}
private void loadNextVideos(List<String> tags) {
Context _mContext = getApplication().getApplicationContext();
new Thread(() -> {
try {
RetrofitPeertubeAPI api = new RetrofitPeertubeAPI(_mContext);
APIResponse apiResponse = api.searchNextVideos(tags);
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = () -> apiResponseMutableLiveData.setValue(apiResponse);
mainHandler.post(myRunnable);
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
}