Manage Peertube videos
This commit is contained in:
parent
fc4cbc5334
commit
a48f997ae3
|
@ -125,7 +125,7 @@ public class MediaActivity extends BaseActivity implements OnDownloadInterface {
|
|||
|
||||
ScreenSlidePagerAdapter mPagerAdapter = new ScreenSlidePagerAdapter(MediaActivity.this);
|
||||
binding.mediaViewpager.setAdapter(mPagerAdapter);
|
||||
|
||||
binding.mediaViewpager.setSaveEnabled(false);
|
||||
binding.mediaViewpager.setCurrentItem(mediaPosition - 1);
|
||||
binding.haulerView.setOnDragDismissedListener(dragDirection -> ActivityCompat.finishAfterTransition(MediaActivity.this));
|
||||
registerReceiver(onDownloadComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
|
||||
|
|
|
@ -83,6 +83,7 @@ public class SearchResultTabActivity extends BaseActivity {
|
|||
binding.searchTabLayout.setTabIconTint(ThemeHelper.getColorStateList(SearchResultTabActivity.this));
|
||||
ScreenSlidePagerAdapter mPagerAdapter = new ScreenSlidePagerAdapter(SearchResultTabActivity.this);
|
||||
binding.searchViewpager.setAdapter(mPagerAdapter);
|
||||
binding.searchViewpager.setSaveEnabled(false);
|
||||
binding.searchViewpager.setOffscreenPageLimit(3);
|
||||
new TabLayoutMediator(binding.searchTabLayout, binding.searchViewpager,
|
||||
(tab, position) -> {
|
||||
|
|
|
@ -224,4 +224,8 @@ public interface MastodonTimelinesService {
|
|||
@Query("count") int count
|
||||
);
|
||||
|
||||
@GET("api/v1/videos/{id}")
|
||||
Call<PeertubeVideo.Video> getPeertubeVideo(
|
||||
@Path("id") String id
|
||||
);
|
||||
}
|
||||
|
|
|
@ -44,4 +44,6 @@ public class Attachment implements Serializable {
|
|||
@SerializedName("local_path")
|
||||
public String local_path;
|
||||
|
||||
public String peertubeHost = null;
|
||||
public String peertubeId = null;
|
||||
}
|
||||
|
|
|
@ -56,9 +56,11 @@ public class PeertubeVideo implements Serializable {
|
|||
status.account = account;
|
||||
List<Attachment> attachmentList = new ArrayList<>();
|
||||
Attachment attachment = new Attachment();
|
||||
attachment.type = "video/mp4";
|
||||
attachment.type = "video";
|
||||
attachment.url = "https://" + peertubeVideo.account.host + peertubeVideo.embedPath;
|
||||
attachment.preview_url = "https://" + peertubeVideo.account.host + peertubeVideo.thumbnailPath;
|
||||
attachment.peertubeId = peertubeVideo.uuid;
|
||||
attachment.peertubeHost = peertubeVideo.account.host;
|
||||
attachmentList.add(attachment);
|
||||
status.media_attachments = attachmentList;
|
||||
return status;
|
||||
|
@ -111,11 +113,33 @@ public class PeertubeVideo implements Serializable {
|
|||
public Date updatedAt;
|
||||
@SerializedName("uuid")
|
||||
public String uuid;
|
||||
|
||||
@SerializedName("files")
|
||||
public List<File> files;
|
||||
@SerializedName("views")
|
||||
public int views;
|
||||
}
|
||||
|
||||
public class File implements Serializable {
|
||||
@SerializedName("fileDownloadUrl")
|
||||
public String fileDownloadUrl;
|
||||
@SerializedName("fileUrl")
|
||||
public String fileUrl;
|
||||
@SerializedName("fps")
|
||||
public int fps;
|
||||
@SerializedName("magnetUri")
|
||||
public String magnetUri;
|
||||
@SerializedName("metadataUrl")
|
||||
public String metadataUrl;
|
||||
@SerializedName("resolution")
|
||||
public Item resolutions;
|
||||
@SerializedName("size")
|
||||
public long size;
|
||||
@SerializedName("torrentDownloadUrl")
|
||||
public String torrentDownloadUrl;
|
||||
@SerializedName("torrentUrl")
|
||||
public String torrentUrl;
|
||||
}
|
||||
|
||||
public static class PeertubeAccount implements Serializable {
|
||||
@SerializedName("avatar")
|
||||
public Avatar avatar;
|
||||
|
|
|
@ -280,6 +280,7 @@ public class Helper {
|
|||
public static final Pattern libredditPattern = Pattern.compile("(www\\.|m\\.)?(reddit\\.com|preview\\.redd\\.it|i\\.redd\\.it|redd\\.it)/(((?!([\"'<])).)*)");
|
||||
public static final Pattern ouichesPattern = Pattern.compile("https?://ouich\\.es/tag/(\\w+)");
|
||||
public static final Pattern xmppPattern = Pattern.compile("xmpp:[-a-zA-Z0-9+$&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]");
|
||||
public static final Pattern peertubePattern = Pattern.compile("(https?://([\\da-z.-]+\\.[a-z.]{2,10}))/videos/watch/(\\w{8}-\\w{4}-\\w{4}-\\w{4}-\\w{12})$");
|
||||
public static final Pattern mediumPattern = Pattern.compile("([\\w@-]*)?\\.?medium.com/@?([/\\w-]+)");
|
||||
public static final Pattern wikipediaPattern = Pattern.compile("([\\w_-]+)\\.wikipedia.org/(((?!([\"'<])).)*)");
|
||||
public static final Pattern codePattern = Pattern.compile("code=([\\w-]+)");
|
||||
|
|
|
@ -433,6 +433,24 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
|||
holder.binding.statusContent.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
|
||||
holder.binding.spoiler.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
|
||||
}
|
||||
|
||||
//If the message contain a link to peertube and no media was added, we add it
|
||||
if (statusToDeal.card != null && statusToDeal.card.url != null && (statusToDeal.media_attachments == null || statusToDeal.media_attachments.size() == 0)) {
|
||||
Matcher matcherLink = Helper.peertubePattern.matcher(statusToDeal.card.url);
|
||||
if (matcherLink.find()) { //Peertubee video
|
||||
List<Attachment> attachmentList = new ArrayList<>();
|
||||
Attachment attachment = new Attachment();
|
||||
attachment.type = "video";
|
||||
attachment.url = matcherLink.group(0);
|
||||
attachment.preview_url = statusToDeal.card.image;
|
||||
attachment.peertubeHost = matcherLink.group(2);
|
||||
attachment.peertubeId = matcherLink.group(3);
|
||||
attachmentList.add(attachment);
|
||||
statusToDeal.media_attachments = attachmentList;
|
||||
adapter.notifyItemChanged(getPositionAsync(notificationList, statusList, statusToDeal));
|
||||
}
|
||||
}
|
||||
|
||||
if (status.card != null && (display_card || status.isFocused)) {
|
||||
if (status.card.width > status.card.height) {
|
||||
holder.binding.cardImageHorizontal.setVisibility(View.VISIBLE);
|
||||
|
|
|
@ -31,6 +31,7 @@ import androidx.annotation.NonNull;
|
|||
import androidx.annotation.Nullable;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
|
@ -51,6 +52,7 @@ import app.fedilab.android.client.entities.api.Attachment;
|
|||
import app.fedilab.android.databinding.FragmentSlideMediaBinding;
|
||||
import app.fedilab.android.helper.CacheDataSourceFactory;
|
||||
import app.fedilab.android.helper.Helper;
|
||||
import app.fedilab.android.viewmodel.mastodon.TimelinesVM;
|
||||
import app.fedilab.android.webview.CustomWebview;
|
||||
import app.fedilab.android.webview.FedilabWebChromeClient;
|
||||
import app.fedilab.android.webview.FedilabWebViewClient;
|
||||
|
@ -198,32 +200,18 @@ public class FragmentMedia extends Fragment {
|
|||
case "video":
|
||||
case "audio":
|
||||
case "gifv":
|
||||
binding.pbarInf.setIndeterminate(false);
|
||||
binding.pbarInf.setScaleY(3f);
|
||||
binding.mediaVideo.setVisibility(View.VISIBLE);
|
||||
Uri uri = Uri.parse(url);
|
||||
|
||||
String userAgent = sharedpreferences.getString(getString(R.string.SET_CUSTOM_USER_AGENT), Helper.USER_AGENT);
|
||||
int video_cache = sharedpreferences.getInt(getString(R.string.SET_VIDEO_CACHE), Helper.DEFAULT_VIDEO_CACHE_MB);
|
||||
ProgressiveMediaSource videoSource;
|
||||
if (video_cache == 0) {
|
||||
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(requireActivity(),
|
||||
Util.getUserAgent(requireActivity(), userAgent), null);
|
||||
videoSource = new ProgressiveMediaSource.Factory(dataSourceFactory)
|
||||
.createMediaSource(uri);
|
||||
if (attachment.peertubeId != null) {
|
||||
//It's a peertube video, we are fetching data
|
||||
TimelinesVM timelinesVM = new ViewModelProvider(requireActivity()).get(TimelinesVM.class);
|
||||
String finalType = type;
|
||||
timelinesVM.getPeertubeVideo(attachment.peertubeHost, attachment.peertubeId).observe(requireActivity(), video -> {
|
||||
if (video != null && video.files != null && video.files.size() > 0) {
|
||||
loadVideo(video.files.get(0).fileUrl, finalType);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
CacheDataSourceFactory cacheDataSourceFactory = new CacheDataSourceFactory(requireActivity());
|
||||
videoSource = new ProgressiveMediaSource.Factory(cacheDataSourceFactory)
|
||||
.createMediaSource(uri);
|
||||
loadVideo(url, type);
|
||||
}
|
||||
player = new SimpleExoPlayer.Builder(requireActivity()).build();
|
||||
if (type.equalsIgnoreCase("gifv"))
|
||||
player.setRepeatMode(Player.REPEAT_MODE_ONE);
|
||||
binding.mediaVideo.setPlayer(player);
|
||||
binding.loader.setVisibility(View.GONE);
|
||||
binding.mediaPicture.setVisibility(View.GONE);
|
||||
player.prepare(videoSource);
|
||||
player.setPlayWhenReady(true);
|
||||
break;
|
||||
case "web":
|
||||
binding.loader.setVisibility(View.GONE);
|
||||
|
@ -261,6 +249,35 @@ public class FragmentMedia extends Fragment {
|
|||
}
|
||||
}
|
||||
|
||||
private void loadVideo(String url, String type) {
|
||||
binding.pbarInf.setIndeterminate(false);
|
||||
binding.pbarInf.setScaleY(3f);
|
||||
binding.mediaVideo.setVisibility(View.VISIBLE);
|
||||
Uri uri = Uri.parse(url);
|
||||
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(requireActivity());
|
||||
String userAgent = sharedpreferences.getString(getString(R.string.SET_CUSTOM_USER_AGENT), Helper.USER_AGENT);
|
||||
int video_cache = sharedpreferences.getInt(getString(R.string.SET_VIDEO_CACHE), Helper.DEFAULT_VIDEO_CACHE_MB);
|
||||
ProgressiveMediaSource videoSource;
|
||||
if (video_cache == 0) {
|
||||
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(requireActivity(),
|
||||
Util.getUserAgent(requireActivity(), userAgent), null);
|
||||
videoSource = new ProgressiveMediaSource.Factory(dataSourceFactory)
|
||||
.createMediaSource(uri);
|
||||
} else {
|
||||
CacheDataSourceFactory cacheDataSourceFactory = new CacheDataSourceFactory(requireActivity());
|
||||
videoSource = new ProgressiveMediaSource.Factory(cacheDataSourceFactory)
|
||||
.createMediaSource(uri);
|
||||
}
|
||||
player = new SimpleExoPlayer.Builder(requireActivity()).build();
|
||||
if (type.equalsIgnoreCase("gifv"))
|
||||
player.setRepeatMode(Player.REPEAT_MODE_ONE);
|
||||
binding.mediaVideo.setPlayer(player);
|
||||
binding.loader.setVisibility(View.GONE);
|
||||
binding.mediaPicture.setVisibility(View.GONE);
|
||||
player.prepare(videoSource);
|
||||
player.setPlayWhenReady(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle saveInstance) {
|
||||
super.onCreate(saveInstance);
|
||||
|
|
|
@ -71,6 +71,7 @@ public class TimelinesVM extends AndroidViewModel {
|
|||
private MutableLiveData<List<StatusDraft>> statusDraftListMutableLiveData;
|
||||
private MutableLiveData<Status> statusMutableLiveData;
|
||||
private MutableLiveData<Statuses> statusesMutableLiveData;
|
||||
private MutableLiveData<PeertubeVideo.Video> peertubeVideoMutableLiveData;
|
||||
private MutableLiveData<Conversations> conversationListMutableLiveData;
|
||||
private MutableLiveData<MastodonList> mastodonListMutableLiveData;
|
||||
private MutableLiveData<List<MastodonList>> mastodonListListMutableLiveData;
|
||||
|
@ -246,6 +247,34 @@ public class TimelinesVM extends AndroidViewModel {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns details for a peertube video
|
||||
*
|
||||
* @return {@link LiveData} containing a {@link PeertubeVideo.Video}
|
||||
*/
|
||||
public LiveData<PeertubeVideo.Video> getPeertubeVideo(@NonNull String instance, String id) {
|
||||
MastodonTimelinesService mastodonTimelinesService = initInstanceOnly(instance);
|
||||
peertubeVideoMutableLiveData = new MutableLiveData<>();
|
||||
new Thread(() -> {
|
||||
Call<PeertubeVideo.Video> publicTlCall = mastodonTimelinesService.getPeertubeVideo(id);
|
||||
PeertubeVideo.Video peertubeVideo = null;
|
||||
try {
|
||||
Response<PeertubeVideo.Video> videoResponse = publicTlCall.execute();
|
||||
if (videoResponse.isSuccessful()) {
|
||||
peertubeVideo = videoResponse.body();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
PeertubeVideo.Video finalPeertubeVideo = peertubeVideo;
|
||||
Runnable myRunnable = () -> peertubeVideoMutableLiveData.setValue(finalPeertubeVideo);
|
||||
mainHandler.post(myRunnable);
|
||||
}).start();
|
||||
return peertubeVideoMutableLiveData;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* View public statuses containing the given hashtag.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue