mirror of
https://framagit.org/tom79/fedilab-tube
synced 2025-02-09 00:28:45 +01:00
Add cast library for Google release only - Checked through Exodus
This commit is contained in:
parent
6d4772da75
commit
b29de141ef
@ -53,6 +53,9 @@ android {
|
||||
buildConfigField "boolean", "sepia_search", "false"
|
||||
buildConfigField "boolean", "instance_switcher", "true"
|
||||
buildConfigField "boolean", "allow_remote_connections", "false"
|
||||
buildConfigField "boolean", "google_cast_lib", "false"
|
||||
buildConfigField "int", "cast_enabled", "0"
|
||||
buildConfigField "int", "default_theme", "2"
|
||||
}
|
||||
google_peertube_apps_educ {
|
||||
applicationId "app.fedilab.fedilabtube"
|
||||
@ -65,6 +68,9 @@ android {
|
||||
buildConfigField "boolean", "sepia_search", "false"
|
||||
buildConfigField "boolean", "instance_switcher", "true"
|
||||
buildConfigField "boolean", "allow_remote_connections", "false"
|
||||
buildConfigField "boolean", "google_cast_lib", "false"
|
||||
buildConfigField "int", "cast_enabled", "0"
|
||||
buildConfigField "int", "default_theme", "2"
|
||||
}
|
||||
fdroid_full {
|
||||
applicationId "app.fedilab.tubelab"
|
||||
@ -77,6 +83,9 @@ android {
|
||||
buildConfigField "boolean", "sepia_search", "true"
|
||||
buildConfigField "boolean", "instance_switcher", "true"
|
||||
buildConfigField "boolean", "allow_remote_connections", "true"
|
||||
buildConfigField "boolean", "google_cast_lib", "false"
|
||||
buildConfigField "int", "cast_enabled", "0"
|
||||
buildConfigField "int", "default_theme", "2"
|
||||
}
|
||||
google_full {
|
||||
applicationId "app.fedilab.tubelab"
|
||||
@ -89,6 +98,9 @@ android {
|
||||
buildConfigField "boolean", "sepia_search", "true"
|
||||
buildConfigField "boolean", "instance_switcher", "true"
|
||||
buildConfigField "boolean", "allow_remote_connections", "true"
|
||||
buildConfigField "boolean", "google_cast_lib", "true"
|
||||
buildConfigField "int", "cast_enabled", "1"
|
||||
buildConfigField "int", "default_theme", "2"
|
||||
}
|
||||
queermotion {
|
||||
applicationId "org.queermotion.peertube"
|
||||
@ -101,6 +113,9 @@ android {
|
||||
buildConfigField "boolean", "sepia_search", "false"
|
||||
buildConfigField "boolean", "instance_switcher", "false"
|
||||
buildConfigField "boolean", "allow_remote_connections", "false"
|
||||
buildConfigField "boolean", "google_cast_lib", "false"
|
||||
buildConfigField "int", "cast_enabled", "0"
|
||||
buildConfigField "int", "default_theme", "2"
|
||||
}
|
||||
bittube {
|
||||
applicationId "app.fedilab.bittube"
|
||||
@ -113,33 +128,38 @@ android {
|
||||
buildConfigField "boolean", "sepia_search", "false"
|
||||
buildConfigField "boolean", "instance_switcher", "true"
|
||||
buildConfigField "boolean", "allow_remote_connections", "false"
|
||||
buildConfigField "boolean", "google_cast_lib", "true"
|
||||
buildConfigField "int", "cast_enabled", "1"
|
||||
buildConfigField "int", "default_theme", "1"
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
fdroid_peertube_apps_educ {
|
||||
res.srcDirs = ['src/main/res', 'src/acad/res']
|
||||
java.srcDirs = ['src/main/java', 'src/acad/java', 'src/no_google_donation/java']
|
||||
res.srcDirs = ['src/main/res', 'src/acad/res', 'src/no_google_cast_lib/res']
|
||||
java.srcDirs = ['src/main/java', 'src/acad/java', 'src/no_google_donation/java', 'src/no_google_cast_lib/java']
|
||||
}
|
||||
google_peertube_apps_educ {
|
||||
res.srcDirs = ['src/main/res', 'src/acad/res']
|
||||
java.srcDirs = ['src/main/java', 'src/acad/java', 'src/no_google_donation/java']
|
||||
res.srcDirs = ['src/main/res', 'src/acad/res', 'src/no_google_cast_lib/res']
|
||||
java.srcDirs = ['src/main/java', 'src/acad/java', 'src/no_google_donation/java', 'src/no_google_cast_lib/java']
|
||||
}
|
||||
fdroid_full {
|
||||
res.srcDirs = ['src/main/res', 'src/full/res']
|
||||
java.srcDirs = ['src/main/java', 'src/full/java', 'src/no_google_donation/java']
|
||||
res.srcDirs = ['src/main/res', 'src/full/res', 'src/no_google_cast_lib/res']
|
||||
java.srcDirs = ['src/main/java', 'src/full/java', 'src/no_google_donation/java', 'src/no_google_cast_lib/java']
|
||||
}
|
||||
google_full {
|
||||
res.srcDirs = ['src/main/res', 'src/full/res', 'src/google_donation/res']
|
||||
java.srcDirs = ['src/main/java', 'src/full/java', 'src/google_donation/java']
|
||||
res.srcDirs = ['src/main/res', 'src/full/res', 'src/google_donation/res', 'src/google_cast_lib/res']
|
||||
java.srcDirs = ['src/main/java', 'src/full/java', 'src/google_donation/java', 'src/google_cast_lib/java']
|
||||
manifest.srcFile "src/google_cast_lib/AndroidManifest.xml"
|
||||
}
|
||||
queermotion {
|
||||
res.srcDirs = ['src/main/res', 'src/queermotion/res']
|
||||
java.srcDirs = ['src/main/java', 'src/full/java', 'src/no_google_donation/java']
|
||||
res.srcDirs = ['src/main/res', 'src/queermotion/res', 'src/no_google_cast_lib/res']
|
||||
java.srcDirs = ['src/main/java', 'src/full/java', 'src/no_google_donation/java', 'src/no_google_cast_lib/java']
|
||||
}
|
||||
bittube {
|
||||
res.srcDirs = ['src/main/res', 'src/bittube/res']
|
||||
java.srcDirs = ['src/main/java', 'src/full/java', 'src/no_google_donation/java']
|
||||
res.srcDirs = ['src/main/res', 'src/bittube/res', 'src/google_cast_lib/res']
|
||||
java.srcDirs = ['src/main/java', 'src/full/java', 'src/no_google_donation/java', 'src/google_cast_lib/java']
|
||||
manifest.srcFile "src/google_cast_lib/AndroidManifest.xml"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -179,6 +199,7 @@ dependencies {
|
||||
implementation "com.github.mabbas007:TagsEditText:1.0.5"
|
||||
implementation "com.github.bumptech.glide:glide:4.11.0"
|
||||
annotationProcessor "com.github.bumptech.glide:compiler:4.11.0"
|
||||
implementation 'jp.wasabeef:glide-transformations:4.0.0'
|
||||
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
|
||||
implementation "net.gotev:uploadservice:4.5.1"
|
||||
implementation "net.gotev:uploadservice-okhttp:4.5.1"
|
||||
@ -196,17 +217,34 @@ dependencies {
|
||||
implementation "androidx.work:work-runtime:2.4.0"
|
||||
implementation "androidx.work:work-runtime-ktx:2.4.0"
|
||||
|
||||
//custom cast feature
|
||||
implementation 'jp.wasabeef:glide-transformations:4.0.0'
|
||||
implementation 'su.litvak.chromecast:api-v2:0.11.3'
|
||||
implementation 'com.fasterxml.jackson.core:jackson-core:2.12.0'
|
||||
implementation 'org.slf4j:slf4j-simple:1.7.30'
|
||||
|
||||
|
||||
//************ DONATION GOOGLE ONLY **************//
|
||||
google_fullImplementation "com.android.billingclient:billing:3.0.2"
|
||||
|
||||
//************ MATOMO --> acad instances only **************//
|
||||
|
||||
fdroid_peertube_apps_educImplementation 'org.matomo.sdk:tracker:4.1.2'
|
||||
google_peertube_apps_educImplementation 'org.matomo.sdk:tracker:4.1.2'
|
||||
|
||||
//************ CAST **************///
|
||||
|
||||
//---> Google libs (google_full + bittube)
|
||||
google_fullImplementation "androidx.mediarouter:mediarouter:1.2.1"
|
||||
google_fullImplementation 'com.google.android.gms:play-services-cast-framework:19.0.0'
|
||||
bittubeImplementation "androidx.mediarouter:mediarouter:1.2.1"
|
||||
bittubeImplementation 'com.google.android.gms:play-services-cast-framework:19.0.0'
|
||||
//----> Other flavors
|
||||
fdroid_peertube_apps_educImplementation 'su.litvak.chromecast:api-v2:0.11.3'
|
||||
fdroid_peertube_apps_educImplementation 'com.fasterxml.jackson.core:jackson-core:2.12.0'
|
||||
fdroid_peertube_apps_educImplementation 'org.slf4j:slf4j-simple:1.7.30'
|
||||
google_peertube_apps_educImplementation 'su.litvak.chromecast:api-v2:0.11.3'
|
||||
google_peertube_apps_educImplementation 'com.fasterxml.jackson.core:jackson-core:2.12.0'
|
||||
google_peertube_apps_educImplementation 'org.slf4j:slf4j-simple:1.7.30'
|
||||
fdroid_fullImplementation 'su.litvak.chromecast:api-v2:0.11.3'
|
||||
fdroid_fullImplementation 'com.fasterxml.jackson.core:jackson-core:2.12.0'
|
||||
fdroid_fullImplementation 'org.slf4j:slf4j-simple:1.7.30'
|
||||
queermotionImplementation 'su.litvak.chromecast:api-v2:0.11.3'
|
||||
queermotionImplementation 'com.fasterxml.jackson.core:jackson-core:2.12.0'
|
||||
queermotionImplementation 'org.slf4j:slf4j-simple:1.7.30'
|
||||
|
||||
}
|
18
app/src/google_cast_lib/AndroidManifest.xml
Normal file
18
app/src/google_cast_lib/AndroidManifest.xml
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="app.fedilab.fedilabtube">
|
||||
|
||||
<application>
|
||||
<activity
|
||||
android:name=".PeertubeActivity"
|
||||
tools:node="merge">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".PeertubeActivity" />
|
||||
</activity>
|
||||
<meta-data
|
||||
android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
|
||||
android:value="app.fedilab.fedilabtube.provider.CastOptionsProvider" />
|
||||
</application>
|
||||
</manifest>
|
@ -0,0 +1,41 @@
|
||||
package app.fedilab.fedilabtube;
|
||||
/* Copyright 2021 Thomas Schneider
|
||||
*
|
||||
* This file is a part of TubeLab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* TubeLab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with TubeLab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import app.fedilab.fedilabtube.databinding.ActivityMainBinding;
|
||||
|
||||
public class BaseMainActivity extends AppCompatActivity {
|
||||
|
||||
protected ActivityMainBinding binding;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
binding = ActivityMainBinding.inflate(getLayoutInflater());
|
||||
View view = binding.getRoot();
|
||||
setContentView(view);
|
||||
}
|
||||
|
||||
//Method for discovering cast devices
|
||||
public void discoverCast() {
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,177 @@
|
||||
package app.fedilab.fedilabtube;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
||||
import com.google.android.gms.cast.MediaInfo;
|
||||
import com.google.android.gms.cast.MediaMetadata;
|
||||
import com.google.android.gms.cast.framework.CastButtonFactory;
|
||||
import com.google.android.gms.cast.framework.CastContext;
|
||||
import com.google.android.gms.cast.framework.CastSession;
|
||||
import com.google.android.gms.cast.framework.SessionManagerListener;
|
||||
import com.google.android.gms.cast.framework.media.RemoteMediaClient;
|
||||
import com.google.android.gms.common.images.WebImage;
|
||||
|
||||
import app.fedilab.fedilabtube.client.data.VideoData;
|
||||
import app.fedilab.fedilabtube.databinding.ActivityPeertubeBinding;
|
||||
import app.fedilab.fedilabtube.helper.Helper;
|
||||
|
||||
/* Copyright 2021 Thomas Schneider
|
||||
*
|
||||
* This file is a part of TubeLab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* TubeLab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with TubeLab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
public class BasePeertubeActivity extends AppCompatActivity {
|
||||
|
||||
protected ActivityPeertubeBinding binding;
|
||||
protected VideoData.Video peertube;
|
||||
protected SimpleExoPlayer player;
|
||||
protected String videoURL;
|
||||
protected String subtitlesStr;
|
||||
|
||||
private CastContext mCastContext;
|
||||
private CastSession mCastSession;
|
||||
private SessionManagerListener<CastSession> mSessionManagerListener;
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
binding = ActivityPeertubeBinding.inflate(getLayoutInflater());
|
||||
View view = binding.getRoot();
|
||||
setContentView(view);
|
||||
final SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
|
||||
int search_cast = sharedpreferences.getInt(getString(R.string.set_cast_choice), BuildConfig.cast_enabled);
|
||||
if (search_cast == 1) {
|
||||
setupCastListener();
|
||||
mCastContext = CastContext.getSharedInstance(this);
|
||||
mCastSession = mCastContext.getSessionManager().getCurrentCastSession();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected void loadCast() {
|
||||
MediaMetadata movieMetadata = new MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE);
|
||||
|
||||
movieMetadata.putString(MediaMetadata.KEY_TITLE, peertube.getTitle());
|
||||
if (subtitlesStr != null) {
|
||||
movieMetadata.putString(MediaMetadata.KEY_SUBTITLE, subtitlesStr);
|
||||
}
|
||||
movieMetadata.addImage(new WebImage(Uri.parse(peertube.getPreviewPath())));
|
||||
MediaInfo mediaInfo = new MediaInfo.Builder(videoURL)
|
||||
.setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)
|
||||
.setMetadata(movieMetadata)
|
||||
.setStreamDuration(peertube.getDuration() * 1000)
|
||||
.build();
|
||||
if (mCastSession != null) {
|
||||
RemoteMediaClient remoteMediaClient = mCastSession.getRemoteMediaClient();
|
||||
remoteMediaClient.load(mediaInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void setupCastListener() {
|
||||
mSessionManagerListener = new SessionManagerListener<CastSession>() {
|
||||
@Override
|
||||
public void onSessionStarting(CastSession castSession) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSessionStarted(CastSession castSession, String s) {
|
||||
onApplicationConnected(castSession);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSessionStartFailed(CastSession castSession, int i) {
|
||||
onApplicationDisconnected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSessionEnding(CastSession castSession) {
|
||||
onApplicationDisconnected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSessionEnded(CastSession castSession, int i) {
|
||||
onApplicationDisconnected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSessionResuming(CastSession castSession, String s) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSessionResumed(CastSession castSession, boolean b) {
|
||||
onApplicationConnected(castSession);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSessionResumeFailed(CastSession castSession, int i) {
|
||||
onApplicationDisconnected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSessionSuspended(CastSession castSession, int i) {
|
||||
onApplicationDisconnected();
|
||||
}
|
||||
|
||||
private void onApplicationConnected(CastSession castSession) {
|
||||
mCastSession = castSession;
|
||||
supportInvalidateOptionsMenu();
|
||||
player.setPlayWhenReady(false);
|
||||
binding.doubleTapPlayerView.setVisibility(View.INVISIBLE);
|
||||
loadCast();
|
||||
}
|
||||
|
||||
private void onApplicationDisconnected() {
|
||||
binding.doubleTapPlayerView.setVisibility(View.VISIBLE);
|
||||
supportInvalidateOptionsMenu();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
mCastContext.getSessionManager().addSessionManagerListener(
|
||||
mSessionManagerListener, CastSession.class);
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
mCastContext.getSessionManager().removeSessionManagerListener(
|
||||
mSessionManagerListener, CastSession.class);
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
super.onCreateOptionsMenu(menu);
|
||||
getMenuInflater().inflate(R.menu.video_menu, menu);
|
||||
CastButtonFactory.setUpMediaRouteButton(getApplicationContext(),
|
||||
menu,
|
||||
R.id.media_route_button);
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Google LLC. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package app.fedilab.fedilabtube.expandedcontrols;
|
||||
|
||||
import android.view.Menu;
|
||||
|
||||
import com.google.android.gms.cast.framework.CastButtonFactory;
|
||||
import com.google.android.gms.cast.framework.media.widget.ExpandedControllerActivity;
|
||||
|
||||
import app.fedilab.fedilabtube.R;
|
||||
|
||||
|
||||
public class ExpandedControlsActivity extends ExpandedControllerActivity {
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
super.onCreateOptionsMenu(menu);
|
||||
getMenuInflater().inflate(R.menu.video_menu, menu);
|
||||
CastButtonFactory.setUpMediaRouteButton(this, menu, R.id.media_route_button);
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package app.fedilab.fedilabtube.provider;
|
||||
/* Copyright 2021 Thomas Schneider
|
||||
*
|
||||
* This file is a part of TubeLab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* TubeLab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with TubeLab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.google.android.gms.cast.framework.CastOptions;
|
||||
import com.google.android.gms.cast.framework.OptionsProvider;
|
||||
import com.google.android.gms.cast.framework.SessionProvider;
|
||||
import com.google.android.gms.cast.framework.media.CastMediaOptions;
|
||||
import com.google.android.gms.cast.framework.media.NotificationOptions;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import app.fedilab.fedilabtube.BuildConfig;
|
||||
import app.fedilab.fedilabtube.expandedcontrols.ExpandedControlsActivity;
|
||||
import app.fedilab.fedilabtube.helper.Helper;
|
||||
|
||||
|
||||
public class CastOptionsProvider implements OptionsProvider {
|
||||
|
||||
|
||||
@Override
|
||||
public CastOptions getCastOptions(Context context) {
|
||||
NotificationOptions notificationOptions = new NotificationOptions.Builder()
|
||||
.setTargetActivityClassName(ExpandedControlsActivity.class.getName())
|
||||
.build();
|
||||
CastMediaOptions mediaOptions = new CastMediaOptions.Builder()
|
||||
.setNotificationOptions(notificationOptions)
|
||||
.setExpandedControllerActivityClassName(ExpandedControlsActivity.class.getName())
|
||||
.build();
|
||||
return new CastOptions.Builder()
|
||||
.setReceiverApplicationId(BuildConfig.FLAVOR.compareTo("bittube") == 0 ? Helper.CAST_ID_BITTUBE : Helper.CAST_ID)
|
||||
.setCastMediaOptions(mediaOptions)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SessionProvider> getAdditionalSessionProviders(Context context) {
|
||||
return null;
|
||||
}
|
||||
}
|
9
app/src/google_cast_lib/res/menu/video_menu.xml
Normal file
9
app/src/google_cast_lib/res/menu/video_menu.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/media_route_button"
|
||||
android:title="@string/cast"
|
||||
app:actionProviderClass="androidx.mediarouter.app.MediaRouteActionProvider"
|
||||
app:showAsAction="always" />
|
||||
</menu>
|
@ -65,7 +65,7 @@ public class BaseFedilabTube extends MultiDexApplication {
|
||||
|
||||
MultiDex.install(BaseFedilabTube.this);
|
||||
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
int themePref = sharedpreferences.getInt(Helper.SET_THEME, Helper.DEFAULT_MODE);
|
||||
int themePref = sharedpreferences.getInt(Helper.SET_THEME, BuildConfig.default_theme);
|
||||
ThemeHelper.switchTo(themePref);
|
||||
|
||||
|
||||
|
@ -16,17 +16,14 @@ package app.fedilab.fedilabtube;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
@ -37,14 +34,12 @@ import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.SearchView;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.appcompat.widget.TooltipCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentStatePagerAdapter;
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
import androidx.viewpager.widget.PagerAdapter;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
|
||||
@ -53,13 +48,7 @@ import com.kobakei.ratethisapp.RateThisApp;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
@ -73,7 +62,6 @@ import java.util.regex.Pattern;
|
||||
import app.fedilab.fedilabtube.client.RetrofitPeertubeAPI;
|
||||
import app.fedilab.fedilabtube.client.data.AccountData.Account;
|
||||
import app.fedilab.fedilabtube.client.data.InstanceData;
|
||||
import app.fedilab.fedilabtube.client.data.VideoData;
|
||||
import app.fedilab.fedilabtube.client.entities.Error;
|
||||
import app.fedilab.fedilabtube.client.entities.OauthParams;
|
||||
import app.fedilab.fedilabtube.client.entities.PeertubeInformation;
|
||||
@ -95,17 +83,13 @@ import app.fedilab.fedilabtube.sqlite.Sqlite;
|
||||
import app.fedilab.fedilabtube.sqlite.StoredInstanceDAO;
|
||||
import app.fedilab.fedilabtube.viewmodel.TimelineVM;
|
||||
import es.dmoral.toasty.Toasty;
|
||||
import su.litvak.chromecast.api.v2.ChromeCast;
|
||||
import su.litvak.chromecast.api.v2.ChromeCasts;
|
||||
import su.litvak.chromecast.api.v2.ChromeCastsListener;
|
||||
import su.litvak.chromecast.api.v2.MediaStatus;
|
||||
|
||||
import static app.fedilab.fedilabtube.MainActivity.TypeOfConnection.NORMAL;
|
||||
import static app.fedilab.fedilabtube.MainActivity.TypeOfConnection.SURFING;
|
||||
import static app.fedilab.fedilabtube.helper.Helper.peertubeInformation;
|
||||
|
||||
|
||||
public class MainActivity extends AppCompatActivity implements ChromeCastsListener {
|
||||
public class MainActivity extends BaseMainActivity {
|
||||
|
||||
|
||||
public static int PICK_INSTANCE = 5641;
|
||||
@ -113,9 +97,8 @@ public class MainActivity extends AppCompatActivity implements ChromeCastsListen
|
||||
public static UserMe userMe;
|
||||
public static InstanceData.InstanceConfig instanceConfig;
|
||||
public static TypeOfConnection typeOfConnection;
|
||||
public static List<ChromeCast> chromeCasts;
|
||||
public static ChromeCast chromeCast;
|
||||
public static boolean chromecastActivated = false;
|
||||
|
||||
|
||||
private DisplayVideosFragment recentFragment, locaFragment, trendingFragment, subscriptionFragment, mostLikedFragment;
|
||||
private DisplayOverviewFragment overviewFragment;
|
||||
private ActivityMainBinding binding;
|
||||
@ -158,8 +141,7 @@ public class MainActivity extends AppCompatActivity implements ChromeCastsListen
|
||||
}
|
||||
return true;
|
||||
};
|
||||
private BroadcastReceiver manage_chromecast;
|
||||
private VideoData.Video castedTube;
|
||||
|
||||
|
||||
@SuppressLint("ApplySharedPref")
|
||||
public static void showRadioButtonDialogFullInstances(Activity activity, boolean storeInDb) {
|
||||
@ -234,123 +216,20 @@ public class MainActivity extends AppCompatActivity implements ChromeCastsListen
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void newChromeCastDiscovered(ChromeCast chromeCast) {
|
||||
if (chromeCasts == null) {
|
||||
chromeCasts = new ArrayList<>();
|
||||
chromeCasts.add(chromeCast);
|
||||
} else {
|
||||
boolean canBeAdded = true;
|
||||
for (ChromeCast cast : chromeCasts) {
|
||||
if (cast.getName().compareTo(chromeCast.getName()) == 0) {
|
||||
canBeAdded = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (canBeAdded) {
|
||||
chromeCasts.add(chromeCast);
|
||||
}
|
||||
}
|
||||
try {
|
||||
if (chromeCast.isAppRunning(Helper.CAST_ID) && chromeCast.getMediaStatus() != null && chromeCast.getMediaStatus().playerState != null) {
|
||||
if (binding.castInfo.getVisibility() == View.GONE) {
|
||||
binding.castInfo.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void chromeCastRemoved(ChromeCast chromeCast) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
binding = null;
|
||||
ChromeCasts.unregisterListener(this);
|
||||
if (manage_chromecast != null) {
|
||||
LocalBroadcastManager.getInstance(MainActivity.this).unregisterReceiver(manage_chromecast);
|
||||
|
||||
new Thread(() -> {
|
||||
if (chromeCasts != null && chromeCasts.size() > 0) {
|
||||
for (ChromeCast cast : chromeCasts) {
|
||||
try {
|
||||
cast.stopApp();
|
||||
cast.disconnect();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
if (chromeCasts != null) {
|
||||
chromeCasts = null;
|
||||
}
|
||||
if (chromeCast != null) {
|
||||
chromeCast = null;
|
||||
}
|
||||
}
|
||||
|
||||
//Method for discovering cast devices
|
||||
public void discoverCast() {
|
||||
new Thread(() -> {
|
||||
if (chromeCasts != null) {
|
||||
for (ChromeCast cast : chromeCasts) {
|
||||
try {
|
||||
cast.disconnect();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
chromeCasts = null;
|
||||
}
|
||||
chromeCasts = new ArrayList<>();
|
||||
try {
|
||||
List<NetworkInterface> interfaces;
|
||||
interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
|
||||
for (NetworkInterface ni : interfaces) {
|
||||
if ((!ni.isLoopback()) && ni.isUp() && (ni.getName().equals("wlan0"))) {
|
||||
Enumeration<InetAddress> inetAddressEnumeration = ni.getInetAddresses();
|
||||
while (inetAddressEnumeration.hasMoreElements()) {
|
||||
InetAddress inetAddress = inetAddressEnumeration.nextElement();
|
||||
ChromeCasts.restartDiscovery(inetAddress);
|
||||
int tryFind = 0;
|
||||
while (ChromeCasts.get().isEmpty() && tryFind < 5) {
|
||||
try {
|
||||
//noinspection BusyWait
|
||||
Thread.sleep(1000);
|
||||
tryFind++;
|
||||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ChromeCasts.stopDiscovery();
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
Runnable myRunnable = this::invalidateOptionsMenu;
|
||||
mainHandler.post(myRunnable);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
binding = ActivityMainBinding.inflate(getLayoutInflater());
|
||||
View view = binding.getRoot();
|
||||
setContentView(view);
|
||||
ChromeCastsListener chromeCastsListener = this;
|
||||
ChromeCasts.registerListener(chromeCastsListener);
|
||||
binding = super.binding;
|
||||
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
@ -462,92 +341,10 @@ public class MainActivity extends AppCompatActivity implements ChromeCastsListen
|
||||
}
|
||||
|
||||
|
||||
binding.castClose.setOnClickListener(v -> {
|
||||
Intent intentBC = new Intent(Helper.RECEIVE_CAST_SETTINGS);
|
||||
Bundle b = new Bundle();
|
||||
b.putInt("displayed", 0);
|
||||
intentBC.putExtras(b);
|
||||
LocalBroadcastManager.getInstance(MainActivity.this).sendBroadcast(intentBC);
|
||||
});
|
||||
|
||||
binding.castTogglePlay.setOnClickListener(v -> {
|
||||
if (chromeCast != null) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
Runnable myRunnable = () -> binding.castTogglePlay.setVisibility(View.GONE);
|
||||
mainHandler.post(myRunnable);
|
||||
int icon = -1;
|
||||
if (chromeCast.getMediaStatus().playerState == MediaStatus.PlayerState.PLAYING) {
|
||||
chromeCast.pause();
|
||||
icon = R.drawable.ic_baseline_play_arrow_32;
|
||||
} else if (chromeCast.getMediaStatus().playerState == MediaStatus.PlayerState.PAUSED) {
|
||||
chromeCast.play();
|
||||
icon = R.drawable.ic_baseline_pause_32;
|
||||
}
|
||||
if (icon != -1) {
|
||||
int finalIcon = icon;
|
||||
myRunnable = () -> binding.castTogglePlay.setImageResource(finalIcon);
|
||||
mainHandler.post(myRunnable);
|
||||
}
|
||||
myRunnable = () -> binding.castTogglePlay.setVisibility(View.VISIBLE);
|
||||
mainHandler.post(myRunnable);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
});
|
||||
manage_chromecast = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
Bundle b = intent.getExtras();
|
||||
assert b != null;
|
||||
int state = b.getInt("state_asked", -1);
|
||||
int displayed = b.getInt("displayed", -1);
|
||||
castedTube = b.getParcelable("castedTube");
|
||||
|
||||
if (state == 1) {
|
||||
discoverCast();
|
||||
} else if (state == 0) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
if (chromeCast != null) {
|
||||
chromeCast.stopApp();
|
||||
chromeCast.disconnect();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
if (displayed == 1) {
|
||||
chromecastActivated = true;
|
||||
if (castedTube != null) {
|
||||
binding.castInfo.setVisibility(View.VISIBLE);
|
||||
Helper.loadGiF(MainActivity.this, castedTube.getThumbnailPath(), binding.castView);
|
||||
binding.castTitle.setText(castedTube.getTitle());
|
||||
binding.castDescription.setText(castedTube.getDescription());
|
||||
}
|
||||
} else if (displayed == 0) {
|
||||
chromecastActivated = false;
|
||||
binding.castInfo.setVisibility(View.GONE);
|
||||
new Thread(() -> {
|
||||
try {
|
||||
if (chromeCast != null) {
|
||||
chromeCast.stopApp();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
};
|
||||
final SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
|
||||
LocalBroadcastManager.getInstance(MainActivity.this).registerReceiver(manage_chromecast, new IntentFilter(Helper.RECEIVE_CAST_SETTINGS));
|
||||
int search_cast = sharedpreferences.getInt(getString(R.string.set_cast_choice), 0);
|
||||
|
||||
int search_cast = sharedpreferences.getInt(getString(R.string.set_cast_choice), BuildConfig.cast_enabled);
|
||||
if (search_cast == 1) {
|
||||
discoverCast();
|
||||
}
|
||||
|
@ -44,7 +44,6 @@ import android.text.method.LinkMovementMethod;
|
||||
import android.text.style.ClickableSpan;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
@ -52,7 +51,6 @@ import android.view.WindowManager;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.TranslateAnimation;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.webkit.MimeTypeMap;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
@ -63,14 +61,12 @@ import android.widget.Toast;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.PopupMenu;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.graphics.drawable.DrawableCompat;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
@ -111,8 +107,6 @@ import com.google.android.material.snackbar.Snackbar;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.text.DateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@ -163,19 +157,12 @@ import app.fedilab.fedilabtube.webview.CustomWebview;
|
||||
import app.fedilab.fedilabtube.webview.MastalabWebChromeClient;
|
||||
import app.fedilab.fedilabtube.webview.MastalabWebViewClient;
|
||||
import es.dmoral.toasty.Toasty;
|
||||
import su.litvak.chromecast.api.v2.ChromeCast;
|
||||
import su.litvak.chromecast.api.v2.MediaStatus;
|
||||
import su.litvak.chromecast.api.v2.Status;
|
||||
|
||||
import static app.fedilab.fedilabtube.MainActivity.chromeCast;
|
||||
import static app.fedilab.fedilabtube.MainActivity.chromeCasts;
|
||||
import static app.fedilab.fedilabtube.MainActivity.chromecastActivated;
|
||||
import static app.fedilab.fedilabtube.client.RetrofitPeertubeAPI.ActionType.ADD_COMMENT;
|
||||
import static app.fedilab.fedilabtube.client.RetrofitPeertubeAPI.ActionType.RATEVIDEO;
|
||||
import static app.fedilab.fedilabtube.client.RetrofitPeertubeAPI.ActionType.REPLY;
|
||||
import static app.fedilab.fedilabtube.client.RetrofitPeertubeAPI.ActionType.REPORT_ACCOUNT;
|
||||
import static app.fedilab.fedilabtube.client.RetrofitPeertubeAPI.ActionType.REPORT_VIDEO;
|
||||
import static app.fedilab.fedilabtube.helper.Helper.CAST_ID;
|
||||
import static app.fedilab.fedilabtube.helper.Helper.canMakeAction;
|
||||
import static app.fedilab.fedilabtube.helper.Helper.getAttColor;
|
||||
import static app.fedilab.fedilabtube.helper.Helper.isLoggedIn;
|
||||
@ -184,15 +171,13 @@ import static app.fedilab.fedilabtube.helper.Helper.peertubeInformation;
|
||||
import static com.google.android.exoplayer2.Player.MEDIA_ITEM_TRANSITION_REASON_AUTO;
|
||||
|
||||
|
||||
public class PeertubeActivity extends AppCompatActivity implements CommentListAdapter.AllCommentRemoved, Player.EventListener, VideoListener, TorrentListener, MenuAdapter.ItemClicked, MenuItemAdapter.ItemAction {
|
||||
public class PeertubeActivity extends BasePeertubeActivity implements CommentListAdapter.AllCommentRemoved, Player.EventListener, VideoListener, TorrentListener, MenuAdapter.ItemClicked, MenuItemAdapter.ItemAction {
|
||||
|
||||
public static String video_id;
|
||||
public static List<String> playedVideos = new ArrayList<>();
|
||||
private String peertubeInstance, videoUuid;
|
||||
private ImageView fullScreenIcon;
|
||||
private SimpleExoPlayer player;
|
||||
private boolean fullScreenMode;
|
||||
private VideoData.Video peertube;
|
||||
private int mode;
|
||||
private Map<String, List<PlaylistExist>> playlists;
|
||||
private boolean playInMinimized, autoPlay, autoFullscreen;
|
||||
@ -218,7 +203,7 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
|
||||
private String currentCaption;
|
||||
private boolean isRemote;
|
||||
private boolean willPlayFromIntent;
|
||||
private String chromeCastVideoURL;
|
||||
|
||||
private app.fedilab.fedilabtube.client.mastodon.Status status;
|
||||
Uri captionURI;
|
||||
String captionLang;
|
||||
@ -307,10 +292,7 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
binding = ActivityPeertubeBinding.inflate(getLayoutInflater());
|
||||
View view = binding.getRoot();
|
||||
setContentView(view);
|
||||
binding = super.binding;
|
||||
videoOrientationType = videoOrientation.LANDSCAPE;
|
||||
max_id = "0";
|
||||
SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||
@ -512,34 +494,7 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
|
||||
}
|
||||
});
|
||||
|
||||
binding.castPlay.setOnClickListener(v -> {
|
||||
binding.castLoader.setVisibility(View.VISIBLE);
|
||||
if (chromeCast != null) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
int icon = -1;
|
||||
if (chromeCast.getMediaStatus().playerState == MediaStatus.PlayerState.PLAYING) {
|
||||
chromeCast.pause();
|
||||
icon = R.drawable.ic_baseline_play_arrow_32;
|
||||
} else if (chromeCast.getMediaStatus().playerState == MediaStatus.PlayerState.PAUSED) {
|
||||
chromeCast.play();
|
||||
icon = R.drawable.ic_baseline_pause_32;
|
||||
}
|
||||
if (icon != -1) {
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
int finalIcon = icon;
|
||||
Runnable myRunnable = () -> binding.castPlay.setImageResource(finalIcon);
|
||||
mainHandler.post(myRunnable);
|
||||
}
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
Runnable myRunnable = () -> binding.castLoader.setVisibility(View.GONE);
|
||||
mainHandler.post(myRunnable);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -798,20 +753,6 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
|
||||
}).start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(@NotNull Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.video_menu, menu);
|
||||
MenuItem castItem = menu.findItem(R.id.action_cast);
|
||||
if (chromeCasts != null && chromeCasts.size() > 0) {
|
||||
castItem.setVisible(true);
|
||||
if (chromeCast != null && chromeCast.isConnected()) {
|
||||
castItem.setIcon(R.drawable.ic_baseline_cast_connected_24);
|
||||
} else {
|
||||
castItem.setIcon(R.drawable.ic_baseline_cast_24);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
@ -821,101 +762,6 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
|
||||
}
|
||||
finish();
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.action_cast) {
|
||||
if (chromeCasts != null && chromeCasts.size() > 0) {
|
||||
String[] chromecast_choice = new String[chromeCasts.size()];
|
||||
AlertDialog.Builder alt_bld = new AlertDialog.Builder(this);
|
||||
alt_bld.setTitle(R.string.chromecast_choice);
|
||||
int i = 0;
|
||||
for (ChromeCast cc : chromeCasts) {
|
||||
chromecast_choice[i] = cc.getTitle();
|
||||
i++;
|
||||
}
|
||||
i = 0;
|
||||
for (ChromeCast cc : chromeCasts) {
|
||||
if (chromecastActivated && cc.isConnected()) {
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
alt_bld.setSingleChoiceItems(chromecast_choice, i, (dialog, position) -> {
|
||||
chromeCast = chromeCasts.get(position);
|
||||
new Thread(() -> {
|
||||
if (chromeCast != null) {
|
||||
Intent intentBC = new Intent(Helper.RECEIVE_CAST_SETTINGS);
|
||||
Bundle b = new Bundle();
|
||||
if (chromecastActivated) {
|
||||
b.putInt("displayed", 0);
|
||||
intentBC.putExtras(b);
|
||||
LocalBroadcastManager.getInstance(PeertubeActivity.this).sendBroadcast(intentBC);
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
Runnable myRunnable = () -> {
|
||||
binding.doubleTapPlayerView.setVisibility(View.VISIBLE);
|
||||
binding.castController.setVisibility(View.GONE);
|
||||
};
|
||||
mainHandler.post(myRunnable);
|
||||
|
||||
} else {
|
||||
b.putInt("displayed", 1);
|
||||
b.putParcelable("castedTube", peertube);
|
||||
intentBC.putExtras(b);
|
||||
LocalBroadcastManager.getInstance(PeertubeActivity.this).sendBroadcast(intentBC);
|
||||
try {
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
Runnable myRunnable = () -> {
|
||||
invalidateOptionsMenu();
|
||||
binding.castLoader.setVisibility(View.VISIBLE);
|
||||
player.setPlayWhenReady(false);
|
||||
binding.doubleTapPlayerView.setVisibility(View.GONE);
|
||||
binding.castController.setVisibility(View.VISIBLE);
|
||||
dialog.dismiss();
|
||||
if (chromeCastVideoURL != null) {
|
||||
if (player != null && player.getCurrentPosition() > 0) {
|
||||
chromeCastVideoURL += "?start=" + (player.getCurrentPosition() / 1000);
|
||||
}
|
||||
}
|
||||
};
|
||||
mainHandler.post(myRunnable);
|
||||
if (!chromeCast.isConnected()) {
|
||||
chromeCast.connect();
|
||||
}
|
||||
myRunnable = this::invalidateOptionsMenu;
|
||||
mainHandler.post(myRunnable);
|
||||
Status status = chromeCast.getStatus();
|
||||
if (chromeCast.isAppAvailable(CAST_ID) && !status.isAppRunning(CAST_ID)) {
|
||||
chromeCast.launchApp(CAST_ID);
|
||||
}
|
||||
|
||||
if (chromeCastVideoURL != null) {
|
||||
String mime = MimeTypeMap.getFileExtensionFromUrl(chromeCastVideoURL);
|
||||
chromeCast.setRequestTimeout(60000);
|
||||
chromeCast.load(peertube.getTitle(), null, chromeCastVideoURL, mime);
|
||||
chromeCast.play();
|
||||
binding.castPlay.setImageResource(R.drawable.ic_baseline_pause_32);
|
||||
}
|
||||
myRunnable = () -> binding.castLoader.setVisibility(View.GONE);
|
||||
mainHandler.post(myRunnable);
|
||||
} catch (IOException | GeneralSecurityException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
Runnable myRunnable = () -> {
|
||||
invalidateOptionsMenu();
|
||||
dialog.dismiss();
|
||||
};
|
||||
mainHandler.post(myRunnable);
|
||||
|
||||
}
|
||||
}).start();
|
||||
|
||||
});
|
||||
alt_bld.setPositiveButton(R.string.close, (dialog, id) -> dialog.dismiss());
|
||||
AlertDialog alert = alt_bld.create();
|
||||
alert.show();
|
||||
}
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
@ -1417,6 +1263,7 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Manage video to play with different factors
|
||||
*
|
||||
@ -1429,7 +1276,10 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
|
||||
* @param lang String ("en","fr", etc.)
|
||||
*/
|
||||
private void stream(VideoData.Video video, String localTorrentUrl, String resolution, boolean autoPlay, long position, Uri subtitles, String lang) {
|
||||
String videoURL = localTorrentUrl == null ? video.getFileUrl(resolution, PeertubeActivity.this) : localTorrentUrl;
|
||||
videoURL = localTorrentUrl == null ? video.getFileUrl(resolution, PeertubeActivity.this) : localTorrentUrl;
|
||||
if (subtitles != null) {
|
||||
subtitlesStr = subtitles.toString();
|
||||
}
|
||||
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
|
||||
int video_cache = sharedpreferences.getInt(Helper.SET_VIDEO_CACHE, Helper.DEFAULT_VIDEO_CACHE_MB);
|
||||
if (videoURL != null && (videoURL.endsWith(".torrent") || videoURL.startsWith("magnet"))) {
|
||||
@ -1503,6 +1353,7 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
|
||||
if (autoPlay) {
|
||||
binding.doubleTapPlayerView.hideController();
|
||||
}
|
||||
// loadCast(video, videoURL, subtitles!=null?subtitles.toString():null);
|
||||
}
|
||||
|
||||
private void fetchComments() {
|
||||
@ -1544,7 +1395,7 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
|
||||
snackbar.show();
|
||||
return;
|
||||
}
|
||||
chromeCastVideoURL = videoURL;
|
||||
|
||||
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
|
||||
String nsfwAction = sharedpreferences.getString(getString(R.string.set_video_sensitive_choice), Helper.BLUR);
|
||||
if (promptNSFW && peertube != null && peertube.isNsfw() && (nsfwAction.compareTo(Helper.BLUR) == 0 || nsfwAction.compareTo(Helper.DO_NOT_LIST) == 0)) {
|
||||
|
@ -34,6 +34,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import app.fedilab.fedilabtube.BuildConfig;
|
||||
import app.fedilab.fedilabtube.MainActivity;
|
||||
import app.fedilab.fedilabtube.R;
|
||||
import app.fedilab.fedilabtube.client.RetrofitPeertubeAPI;
|
||||
@ -315,7 +316,7 @@ public class SettingsFragment extends PreferenceFragmentCompat implements Shared
|
||||
CharSequence[] entriesTheme = arrayTheme.toArray(new CharSequence[0]);
|
||||
CharSequence[] entryValuesTheme = new CharSequence[3];
|
||||
final SharedPreferences sharedpref = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
int currentTheme = sharedpref.getInt(Helper.SET_THEME, Helper.DEFAULT_MODE);
|
||||
int currentTheme = sharedpref.getInt(Helper.SET_THEME, BuildConfig.default_theme);
|
||||
entryValuesTheme[0] = String.valueOf(Helper.LIGHT_MODE);
|
||||
entryValuesTheme[1] = String.valueOf(Helper.DARK_MODE);
|
||||
entryValuesTheme[2] = String.valueOf(Helper.DEFAULT_MODE);
|
||||
@ -407,7 +408,7 @@ public class SettingsFragment extends PreferenceFragmentCompat implements Shared
|
||||
set_video_in_list_choice.setChecked(videosInList);
|
||||
|
||||
//****** Allow Chromecast *******
|
||||
int cast = sharedpref.getInt(getString(R.string.set_cast_choice), 0);
|
||||
int cast = sharedpref.getInt(getString(R.string.set_cast_choice), BuildConfig.cast_enabled);
|
||||
SwitchPreference set_cast_choice = findPreference(getString(R.string.set_cast_choice));
|
||||
assert set_cast_choice != null;
|
||||
set_cast_choice.setChecked(cast == 1);
|
||||
|
@ -135,6 +135,7 @@ public class Helper {
|
||||
public static final String VIDEO_ID = "video_id_update";
|
||||
public static final String APP_PREFS = "app_prefs";
|
||||
public static final String CAST_ID = "D402501A";
|
||||
public static final String CAST_ID_BITTUBE = "CBA4A31D";
|
||||
public static final int VIDEOS_PER_PAGE = 10;
|
||||
public static final String RECEIVE_ACTION = "receive_action";
|
||||
public static final String SET_UNFOLLOW_VALIDATION = "set_unfollow_validation";
|
||||
|
@ -244,7 +244,7 @@ public class AccountDAO {
|
||||
public List<Account> getAllPeertubeAccount() {
|
||||
|
||||
try {
|
||||
Cursor c = db.query(Sqlite.TABLE_USER_ACCOUNT, null, Sqlite.COL_SOFTWARE + "=? OR " + Sqlite.COL_SOFTWARE + "is null", new String[]{"PEERTUBE"}, null, null, Sqlite.COL_INSTANCE + " ASC", null);
|
||||
Cursor c = db.query(Sqlite.TABLE_USER_ACCOUNT, null, Sqlite.COL_SOFTWARE + "=? OR " + Sqlite.COL_SOFTWARE + " is null", new String[]{"PEERTUBE"}, null, null, Sqlite.COL_INSTANCE + " ASC", null);
|
||||
return cursorToListUser(c);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
@ -689,6 +689,5 @@
|
||||
android:layout_gravity="center"
|
||||
android:layout_margin="30dp" />
|
||||
</RelativeLayout>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
@ -0,0 +1,261 @@
|
||||
package app.fedilab.fedilabtube;
|
||||
/* Copyright 2021 Thomas Schneider
|
||||
*
|
||||
* This file is a part of TubeLab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* TubeLab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with TubeLab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
|
||||
import app.fedilab.fedilabtube.client.data.VideoData;
|
||||
import app.fedilab.fedilabtube.databinding.ActivityMainBinding;
|
||||
import app.fedilab.fedilabtube.helper.Helper;
|
||||
import su.litvak.chromecast.api.v2.ChromeCast;
|
||||
import su.litvak.chromecast.api.v2.ChromeCasts;
|
||||
import su.litvak.chromecast.api.v2.ChromeCastsListener;
|
||||
import su.litvak.chromecast.api.v2.MediaStatus;
|
||||
|
||||
public abstract class BaseMainActivity extends AppCompatActivity implements ChromeCastsListener {
|
||||
|
||||
public static List<ChromeCast> chromeCasts;
|
||||
public static ChromeCast chromeCast;
|
||||
public static boolean chromecastActivated = false;
|
||||
protected ActivityMainBinding binding;
|
||||
private BroadcastReceiver manage_chromecast;
|
||||
private VideoData.Video castedTube;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
binding = ActivityMainBinding.inflate(getLayoutInflater());
|
||||
View view = binding.getRoot();
|
||||
setContentView(view);
|
||||
ChromeCastsListener chromeCastsListener = this;
|
||||
ChromeCasts.registerListener(chromeCastsListener);
|
||||
|
||||
|
||||
binding.castClose.setOnClickListener(v -> {
|
||||
Intent intentBC = new Intent(Helper.RECEIVE_CAST_SETTINGS);
|
||||
Bundle b = new Bundle();
|
||||
b.putInt("displayed", 0);
|
||||
intentBC.putExtras(b);
|
||||
LocalBroadcastManager.getInstance(BaseMainActivity.this).sendBroadcast(intentBC);
|
||||
});
|
||||
|
||||
binding.castTogglePlay.setOnClickListener(v -> {
|
||||
if (chromeCast != null) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
Runnable myRunnable = () -> binding.castTogglePlay.setVisibility(View.GONE);
|
||||
mainHandler.post(myRunnable);
|
||||
int icon = -1;
|
||||
if (chromeCast.getMediaStatus().playerState == MediaStatus.PlayerState.PLAYING) {
|
||||
chromeCast.pause();
|
||||
icon = R.drawable.ic_baseline_play_arrow_32;
|
||||
} else if (chromeCast.getMediaStatus().playerState == MediaStatus.PlayerState.PAUSED) {
|
||||
chromeCast.play();
|
||||
icon = R.drawable.ic_baseline_pause_32;
|
||||
}
|
||||
if (icon != -1) {
|
||||
int finalIcon = icon;
|
||||
myRunnable = () -> binding.castTogglePlay.setImageResource(finalIcon);
|
||||
mainHandler.post(myRunnable);
|
||||
}
|
||||
myRunnable = () -> binding.castTogglePlay.setVisibility(View.VISIBLE);
|
||||
mainHandler.post(myRunnable);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
manage_chromecast = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
Bundle b = intent.getExtras();
|
||||
assert b != null;
|
||||
int state = b.getInt("state_asked", -1);
|
||||
int displayed = b.getInt("displayed", -1);
|
||||
castedTube = b.getParcelable("castedTube");
|
||||
|
||||
if (state == 1) {
|
||||
discoverCast();
|
||||
} else if (state == 0) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
if (chromeCast != null) {
|
||||
chromeCast.stopApp();
|
||||
chromeCast.disconnect();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
if (displayed == 1) {
|
||||
chromecastActivated = true;
|
||||
if (castedTube != null) {
|
||||
binding.castInfo.setVisibility(View.VISIBLE);
|
||||
Helper.loadGiF(BaseMainActivity.this, castedTube.getThumbnailPath(), binding.castView);
|
||||
binding.castTitle.setText(castedTube.getTitle());
|
||||
binding.castDescription.setText(castedTube.getDescription());
|
||||
}
|
||||
} else if (displayed == 0) {
|
||||
chromecastActivated = false;
|
||||
binding.castInfo.setVisibility(View.GONE);
|
||||
new Thread(() -> {
|
||||
try {
|
||||
if (chromeCast != null) {
|
||||
chromeCast.stopApp();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
};
|
||||
LocalBroadcastManager.getInstance(BaseMainActivity.this).registerReceiver(manage_chromecast, new IntentFilter(Helper.RECEIVE_CAST_SETTINGS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void newChromeCastDiscovered(ChromeCast chromeCast) {
|
||||
if (chromeCasts == null) {
|
||||
chromeCasts = new ArrayList<>();
|
||||
chromeCasts.add(chromeCast);
|
||||
} else {
|
||||
boolean canBeAdded = true;
|
||||
for (ChromeCast cast : chromeCasts) {
|
||||
if (cast.getName().compareTo(chromeCast.getName()) == 0) {
|
||||
canBeAdded = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (canBeAdded) {
|
||||
chromeCasts.add(chromeCast);
|
||||
}
|
||||
}
|
||||
try {
|
||||
if (chromeCast.isAppRunning(Helper.CAST_ID) && chromeCast.getMediaStatus() != null && chromeCast.getMediaStatus().playerState != null) {
|
||||
if (binding.castInfo.getVisibility() == View.GONE) {
|
||||
binding.castInfo.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void chromeCastRemoved(ChromeCast chromeCast) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
ChromeCasts.unregisterListener(this);
|
||||
if (manage_chromecast != null) {
|
||||
LocalBroadcastManager.getInstance(BaseMainActivity.this).unregisterReceiver(manage_chromecast);
|
||||
|
||||
new Thread(() -> {
|
||||
if (chromeCasts != null && chromeCasts.size() > 0) {
|
||||
for (ChromeCast cast : chromeCasts) {
|
||||
try {
|
||||
cast.stopApp();
|
||||
cast.disconnect();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
if (chromeCasts != null) {
|
||||
chromeCasts = null;
|
||||
}
|
||||
if (chromeCast != null) {
|
||||
chromeCast = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Method for discovering cast devices
|
||||
public void discoverCast() {
|
||||
|
||||
new Thread(() -> {
|
||||
if (chromeCasts != null) {
|
||||
for (ChromeCast cast : chromeCasts) {
|
||||
try {
|
||||
cast.disconnect();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
chromeCasts = null;
|
||||
}
|
||||
chromeCasts = new ArrayList<>();
|
||||
try {
|
||||
List<NetworkInterface> interfaces;
|
||||
interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
|
||||
for (NetworkInterface ni : interfaces) {
|
||||
if ((!ni.isLoopback()) && ni.isUp() && (ni.getName().equals("wlan0"))) {
|
||||
Enumeration<InetAddress> inetAddressEnumeration = ni.getInetAddresses();
|
||||
while (inetAddressEnumeration.hasMoreElements()) {
|
||||
InetAddress inetAddress = inetAddressEnumeration.nextElement();
|
||||
ChromeCasts.restartDiscovery(inetAddress);
|
||||
int tryFind = 0;
|
||||
while (ChromeCasts.get().isEmpty() && tryFind < 5) {
|
||||
try {
|
||||
//noinspection BusyWait
|
||||
Thread.sleep(1000);
|
||||
tryFind++;
|
||||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ChromeCasts.stopDiscovery();
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
Runnable myRunnable = this::invalidateOptionsMenu;
|
||||
mainHandler.post(myRunnable);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,206 @@
|
||||
package app.fedilab.fedilabtube;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.webkit.MimeTypeMap;
|
||||
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
|
||||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.GeneralSecurityException;
|
||||
|
||||
import app.fedilab.fedilabtube.client.data.VideoData;
|
||||
import app.fedilab.fedilabtube.databinding.ActivityPeertubeBinding;
|
||||
import app.fedilab.fedilabtube.helper.Helper;
|
||||
import su.litvak.chromecast.api.v2.ChromeCast;
|
||||
import su.litvak.chromecast.api.v2.MediaStatus;
|
||||
import su.litvak.chromecast.api.v2.Status;
|
||||
|
||||
import static app.fedilab.fedilabtube.helper.Helper.CAST_ID;
|
||||
|
||||
/* Copyright 2021 Thomas Schneider
|
||||
*
|
||||
* This file is a part of TubeLab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* TubeLab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with TubeLab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
public class BasePeertubeActivity extends AppCompatActivity {
|
||||
|
||||
protected ActivityPeertubeBinding binding;
|
||||
private String chromeCastVideoURL;
|
||||
protected VideoData.Video peertube;
|
||||
protected SimpleExoPlayer player;
|
||||
protected String videoURL;
|
||||
protected String subtitlesStr;
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
binding = ActivityPeertubeBinding.inflate(getLayoutInflater());
|
||||
View view = binding.getRoot();
|
||||
setContentView(view);
|
||||
binding.castPlay.setOnClickListener(v -> {
|
||||
binding.castLoader.setVisibility(View.VISIBLE);
|
||||
if (BaseMainActivity.chromeCast != null) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
int icon = -1;
|
||||
if (BaseMainActivity.chromeCast.getMediaStatus().playerState == MediaStatus.PlayerState.PLAYING) {
|
||||
BaseMainActivity.chromeCast.pause();
|
||||
icon = R.drawable.ic_baseline_play_arrow_32;
|
||||
} else if (BaseMainActivity.chromeCast.getMediaStatus().playerState == MediaStatus.PlayerState.PAUSED) {
|
||||
BaseMainActivity.chromeCast.play();
|
||||
icon = R.drawable.ic_baseline_pause_32;
|
||||
}
|
||||
if (icon != -1) {
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
int finalIcon = icon;
|
||||
Runnable myRunnable = () -> binding.castPlay.setImageResource(finalIcon);
|
||||
mainHandler.post(myRunnable);
|
||||
}
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
Runnable myRunnable = () -> binding.castLoader.setVisibility(View.GONE);
|
||||
mainHandler.post(myRunnable);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == R.id.action_cast) {
|
||||
if (BaseMainActivity.chromeCasts != null && BaseMainActivity.chromeCasts.size() > 0) {
|
||||
String[] chromecast_choice = new String[BaseMainActivity.chromeCasts.size()];
|
||||
AlertDialog.Builder alt_bld = new AlertDialog.Builder(this);
|
||||
alt_bld.setTitle(R.string.chromecast_choice);
|
||||
int i = 0;
|
||||
for (ChromeCast cc : BaseMainActivity.chromeCasts) {
|
||||
chromecast_choice[i] = cc.getTitle();
|
||||
i++;
|
||||
}
|
||||
i = 0;
|
||||
for (ChromeCast cc : BaseMainActivity.chromeCasts) {
|
||||
if (BaseMainActivity.chromecastActivated && cc.isConnected()) {
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
alt_bld.setSingleChoiceItems(chromecast_choice, i, (dialog, position) -> {
|
||||
BaseMainActivity.chromeCast = BaseMainActivity.chromeCasts.get(position);
|
||||
new Thread(() -> {
|
||||
if (BaseMainActivity.chromeCast != null) {
|
||||
Intent intentBC = new Intent(Helper.RECEIVE_CAST_SETTINGS);
|
||||
Bundle b = new Bundle();
|
||||
if (BaseMainActivity.chromecastActivated) {
|
||||
b.putInt("displayed", 0);
|
||||
intentBC.putExtras(b);
|
||||
LocalBroadcastManager.getInstance(BasePeertubeActivity.this).sendBroadcast(intentBC);
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
Runnable myRunnable = () -> {
|
||||
binding.doubleTapPlayerView.setVisibility(View.VISIBLE);
|
||||
binding.castController.setVisibility(View.GONE);
|
||||
};
|
||||
mainHandler.post(myRunnable);
|
||||
|
||||
} else {
|
||||
b.putInt("displayed", 1);
|
||||
b.putParcelable("castedTube", peertube);
|
||||
intentBC.putExtras(b);
|
||||
LocalBroadcastManager.getInstance(BasePeertubeActivity.this).sendBroadcast(intentBC);
|
||||
try {
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
Runnable myRunnable = () -> {
|
||||
invalidateOptionsMenu();
|
||||
binding.castLoader.setVisibility(View.VISIBLE);
|
||||
player.setPlayWhenReady(false);
|
||||
binding.doubleTapPlayerView.setVisibility(View.GONE);
|
||||
binding.castController.setVisibility(View.VISIBLE);
|
||||
dialog.dismiss();
|
||||
if (chromeCastVideoURL != null) {
|
||||
if (player != null && player.getCurrentPosition() > 0) {
|
||||
chromeCastVideoURL += "?start=" + (player.getCurrentPosition() / 1000);
|
||||
}
|
||||
}
|
||||
};
|
||||
mainHandler.post(myRunnable);
|
||||
if (!BaseMainActivity.chromeCast.isConnected()) {
|
||||
BaseMainActivity.chromeCast.connect();
|
||||
}
|
||||
myRunnable = this::invalidateOptionsMenu;
|
||||
mainHandler.post(myRunnable);
|
||||
Status status = BaseMainActivity.chromeCast.getStatus();
|
||||
if (BaseMainActivity.chromeCast.isAppAvailable(CAST_ID) && !status.isAppRunning(CAST_ID)) {
|
||||
BaseMainActivity.chromeCast.launchApp(CAST_ID);
|
||||
}
|
||||
if (chromeCastVideoURL != null) {
|
||||
String mime = MimeTypeMap.getFileExtensionFromUrl(chromeCastVideoURL);
|
||||
BaseMainActivity.chromeCast.setRequestTimeout(60000);
|
||||
BaseMainActivity.chromeCast.load(peertube.getTitle(), null, chromeCastVideoURL, mime);
|
||||
BaseMainActivity.chromeCast.play();
|
||||
binding.castPlay.setImageResource(R.drawable.ic_baseline_pause_32);
|
||||
}
|
||||
myRunnable = () -> binding.castLoader.setVisibility(View.GONE);
|
||||
mainHandler.post(myRunnable);
|
||||
} catch (IOException | GeneralSecurityException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
Runnable myRunnable = () -> {
|
||||
invalidateOptionsMenu();
|
||||
dialog.dismiss();
|
||||
};
|
||||
mainHandler.post(myRunnable);
|
||||
}
|
||||
}).start();
|
||||
});
|
||||
alt_bld.setPositiveButton(R.string.close, (dialog, id) -> dialog.dismiss());
|
||||
AlertDialog alert = alt_bld.create();
|
||||
alert.show();
|
||||
}
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(@NotNull Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.video_menu, menu);
|
||||
MenuItem castItem = menu.findItem(R.id.action_cast);
|
||||
if (BaseMainActivity.chromeCasts != null && BaseMainActivity.chromeCasts.size() > 0) {
|
||||
castItem.setVisible(true);
|
||||
if (BaseMainActivity.chromeCast != null && BaseMainActivity.chromeCast.isConnected()) {
|
||||
castItem.setIcon(R.drawable.ic_baseline_cast_connected_24);
|
||||
} else {
|
||||
castItem.setIcon(R.drawable.ic_baseline_cast_24);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package app.fedilab.fedilabtube.provider;
|
||||
/* Copyright 2021 Thomas Schneider
|
||||
*
|
||||
* This file is a part of TubeLab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* TubeLab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with TubeLab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
public class CastOptionsProvider {
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user