mirror of
https://framagit.org/tom79/fedilab-tube
synced 2025-06-05 21:09:11 +02:00
Issue #123 - Working cast
This commit is contained in:
@ -157,5 +157,5 @@ dependencies {
|
|||||||
implementation 'jp.wasabeef:glide-transformations:4.0.0'
|
implementation 'jp.wasabeef:glide-transformations:4.0.0'
|
||||||
implementation 'su.litvak.chromecast:api-v2:0.11.3'
|
implementation 'su.litvak.chromecast:api-v2:0.11.3'
|
||||||
implementation 'com.fasterxml.jackson.core:jackson-core:2.12.0'
|
implementation 'com.fasterxml.jackson.core:jackson-core:2.12.0'
|
||||||
|
implementation 'org.slf4j:slf4j-simple:1.7.30'
|
||||||
}
|
}
|
@ -15,9 +15,12 @@
|
|||||||
<string name="set_play_screen_lock_choice" translatable="false">set_play_screen_lock_choice</string>
|
<string name="set_play_screen_lock_choice" translatable="false">set_play_screen_lock_choice</string>
|
||||||
<string name="set_video_in_list_choice" translatable="false">set_video_in_list_choice</string>
|
<string name="set_video_in_list_choice" translatable="false">set_video_in_list_choice</string>
|
||||||
<string name="set_video_sensitive_choice" translatable="false">set_video_sensitive_choice</string>
|
<string name="set_video_sensitive_choice" translatable="false">set_video_sensitive_choice</string>
|
||||||
|
<string name="set_cast_choice" translatable="false">set_cast_choice</string>
|
||||||
|
<string name="set_cast">Activer Chromecast (beta)</string>
|
||||||
<string name="set_video_in_list">Vidéos dans une liste</string>
|
<string name="set_video_in_list">Vidéos dans une liste</string>
|
||||||
<string name="set_video_in_list_description">Change la mise en page pour afficher les vidéos dans une liste</string>
|
<string name="set_video_in_list_description">Change la mise en page pour afficher les vidéos dans une liste</string>
|
||||||
<string name="cast">ChromeCast</string>
|
<string name="cast">ChromeCast</string>
|
||||||
|
<string name="set_cast_description">Permet de découvrir les appareils Chromecast sur le réseau.</string>
|
||||||
<string name="chromecast_choice">Choix de la ChromeCast</string>
|
<string name="chromecast_choice">Choix de la ChromeCast</string>
|
||||||
<string name="_retry">Réessayer</string>
|
<string name="_retry">Réessayer</string>
|
||||||
<string name="refresh_token_failed">Échec de rafraîchissement du jeton d\'accès</string>
|
<string name="refresh_token_failed">Échec de rafraîchissement du jeton d\'accès</string>
|
||||||
|
@ -13,6 +13,9 @@
|
|||||||
<string name="set_fullscreen_choice" translatable="false">set_fullscreen_choice</string>
|
<string name="set_fullscreen_choice" translatable="false">set_fullscreen_choice</string>
|
||||||
<string name="set_play_screen_lock_choice" translatable="false">set_play_screen_lock_choice</string>
|
<string name="set_play_screen_lock_choice" translatable="false">set_play_screen_lock_choice</string>
|
||||||
<string name="set_video_in_list_choice" translatable="false">set_video_in_list_choice</string>
|
<string name="set_video_in_list_choice" translatable="false">set_video_in_list_choice</string>
|
||||||
|
<string name="set_cast_choice" translatable="false">set_cast_choice</string>
|
||||||
|
<string name="set_cast">Enable Chromecast (beta)</string>
|
||||||
|
<string name="set_cast_description">Allow to discover Chromecast devices on the network.</string>
|
||||||
<string name="set_video_sensitive_choice" translatable="false">set_video_sensitive_choice</string>
|
<string name="set_video_sensitive_choice" translatable="false">set_video_sensitive_choice</string>
|
||||||
<string name="set_video_in_list">Videos in list</string>
|
<string name="set_video_in_list">Videos in list</string>
|
||||||
<string name="set_video_in_list_description">Change the layout for displaying videos in a list</string>
|
<string name="set_video_in_list_description">Change the layout for displaying videos in a list</string>
|
||||||
|
@ -16,8 +16,10 @@ package app.fedilab.fedilabtube;
|
|||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
@ -40,6 +42,7 @@ import androidx.appcompat.widget.Toolbar;
|
|||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
import androidx.fragment.app.FragmentStatePagerAdapter;
|
import androidx.fragment.app.FragmentStatePagerAdapter;
|
||||||
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||||
import androidx.viewpager.widget.PagerAdapter;
|
import androidx.viewpager.widget.PagerAdapter;
|
||||||
import androidx.viewpager.widget.ViewPager;
|
import androidx.viewpager.widget.ViewPager;
|
||||||
|
|
||||||
@ -105,6 +108,7 @@ public class MainActivity extends AppCompatActivity implements ChromeCastsListen
|
|||||||
private DisplayVideosFragment recentFragment, locaFragment, trendingFragment, subscriptionFragment, mostLikedFragment;
|
private DisplayVideosFragment recentFragment, locaFragment, trendingFragment, subscriptionFragment, mostLikedFragment;
|
||||||
private DisplayOverviewFragment overviewFragment;
|
private DisplayOverviewFragment overviewFragment;
|
||||||
private ActivityMainBinding binding;
|
private ActivityMainBinding binding;
|
||||||
|
private BroadcastReceiver manage_chromecast;
|
||||||
|
|
||||||
@SuppressLint("ApplySharedPref")
|
@SuppressLint("ApplySharedPref")
|
||||||
public static void showRadioButtonDialogFullInstances(Activity activity, boolean storeInDb) {
|
public static void showRadioButtonDialogFullInstances(Activity activity, boolean storeInDb) {
|
||||||
@ -232,8 +236,22 @@ public class MainActivity extends AppCompatActivity implements ChromeCastsListen
|
|||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
binding = null;
|
binding = null;
|
||||||
ChromeCasts.unregisterListener(this);
|
ChromeCasts.unregisterListener(this);
|
||||||
|
if (manage_chromecast != null) {
|
||||||
|
LocalBroadcastManager.getInstance(MainActivity.this).unregisterReceiver(manage_chromecast);
|
||||||
|
if (chromeCasts != null && chromeCasts.size() > 0) {
|
||||||
|
for (ChromeCast cast : chromeCasts) {
|
||||||
|
try {
|
||||||
|
cast.disconnect();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
chromeCasts = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Method for discovering cast devices
|
||||||
public void discoverCast() {
|
public void discoverCast() {
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
if (chromeCasts != null) {
|
if (chromeCasts != null) {
|
||||||
@ -267,6 +285,7 @@ public class MainActivity extends AppCompatActivity implements ChromeCastsListen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ChromeCasts.stopDiscovery();
|
||||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||||
Runnable myRunnable = this::invalidateOptionsMenu;
|
Runnable myRunnable = this::invalidateOptionsMenu;
|
||||||
mainHandler.post(myRunnable);
|
mainHandler.post(myRunnable);
|
||||||
@ -276,6 +295,7 @@ public class MainActivity extends AppCompatActivity implements ChromeCastsListen
|
|||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
@ -284,7 +304,7 @@ public class MainActivity extends AppCompatActivity implements ChromeCastsListen
|
|||||||
setContentView(view);
|
setContentView(view);
|
||||||
ChromeCastsListener chromeCastsListener = this;
|
ChromeCastsListener chromeCastsListener = this;
|
||||||
ChromeCasts.registerListener(chromeCastsListener);
|
ChromeCasts.registerListener(chromeCastsListener);
|
||||||
discoverCast();
|
|
||||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||||
setSupportActionBar(toolbar);
|
setSupportActionBar(toolbar);
|
||||||
|
|
||||||
@ -388,6 +408,38 @@ public class MainActivity extends AppCompatActivity implements ChromeCastsListen
|
|||||||
if (!BuildConfig.full_instances) {
|
if (!BuildConfig.full_instances) {
|
||||||
PlaylistExportHelper.manageIntentUrl(MainActivity.this, getIntent());
|
PlaylistExportHelper.manageIntentUrl(MainActivity.this, getIntent());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
manage_chromecast = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
Bundle b = intent.getExtras();
|
||||||
|
assert b != null;
|
||||||
|
boolean state = b.getBoolean("state_asked");
|
||||||
|
if (state) {
|
||||||
|
discoverCast();
|
||||||
|
} else {
|
||||||
|
new Thread(() -> {
|
||||||
|
ChromeCasts.get();
|
||||||
|
if (ChromeCasts.get().size() > 0) {
|
||||||
|
for (ChromeCast cast : ChromeCasts.get()) {
|
||||||
|
try {
|
||||||
|
cast.disconnect();
|
||||||
|
} 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));
|
||||||
|
boolean search_cast = sharedpreferences.getBoolean(getString(R.string.set_cast_choice), false);
|
||||||
|
if (search_cast) {
|
||||||
|
discoverCast();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public DisplayVideosFragment getSubscriptionFragment() {
|
public DisplayVideosFragment getSubscriptionFragment() {
|
||||||
|
@ -52,6 +52,7 @@ import android.view.WindowManager;
|
|||||||
import android.view.animation.Animation;
|
import android.view.animation.Animation;
|
||||||
import android.view.animation.TranslateAnimation;
|
import android.view.animation.TranslateAnimation;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
|
import android.webkit.MimeTypeMap;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
@ -150,10 +151,7 @@ import app.fedilab.fedilabtube.webview.CustomWebview;
|
|||||||
import app.fedilab.fedilabtube.webview.MastalabWebChromeClient;
|
import app.fedilab.fedilabtube.webview.MastalabWebChromeClient;
|
||||||
import app.fedilab.fedilabtube.webview.MastalabWebViewClient;
|
import app.fedilab.fedilabtube.webview.MastalabWebViewClient;
|
||||||
import es.dmoral.toasty.Toasty;
|
import es.dmoral.toasty.Toasty;
|
||||||
import su.litvak.chromecast.api.v2.Application;
|
|
||||||
import su.litvak.chromecast.api.v2.ChromeCast;
|
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.Status;
|
import su.litvak.chromecast.api.v2.Status;
|
||||||
|
|
||||||
import static app.fedilab.fedilabtube.client.RetrofitPeertubeAPI.ActionType.ADD_COMMENT;
|
import static app.fedilab.fedilabtube.client.RetrofitPeertubeAPI.ActionType.ADD_COMMENT;
|
||||||
@ -720,26 +718,25 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
chromeCast.connect();
|
|
||||||
|
|
||||||
|
|
||||||
Status status = chromeCast.getStatus();
|
|
||||||
|
|
||||||
Application app = null;
|
|
||||||
if (chromeCast.isAppAvailable(CAST_ID) && !status.isAppRunning(CAST_ID)) {
|
|
||||||
chromeCast.launchApp(CAST_ID);
|
|
||||||
|
|
||||||
}
|
|
||||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||||
Runnable myRunnable = () -> {
|
Runnable myRunnable = () -> {
|
||||||
invalidateOptionsMenu();
|
invalidateOptionsMenu();
|
||||||
|
player.setPlayWhenReady(false);
|
||||||
dialog.dismiss();
|
dialog.dismiss();
|
||||||
};
|
};
|
||||||
|
if (!chromeCast.isConnected()) {
|
||||||
|
chromeCast.connect();
|
||||||
|
}
|
||||||
|
Status status = chromeCast.getStatus();
|
||||||
|
if (chromeCast.isAppAvailable(CAST_ID) && !status.isAppRunning(CAST_ID)) {
|
||||||
|
chromeCast.launchApp(CAST_ID);
|
||||||
|
}
|
||||||
mainHandler.post(myRunnable);
|
mainHandler.post(myRunnable);
|
||||||
if (status.isAppRunning(CAST_ID) && chromeCastVideoURL != null) {
|
if (chromeCastVideoURL != null) {
|
||||||
app = status.getRunningApp();
|
String mime = MimeTypeMap.getFileExtensionFromUrl(chromeCastVideoURL);
|
||||||
chromeCast.load(peertube.getTitle(), "https://" + HelperInstance.getLiveInstance(PeertubeActivity.this) + peertube.getThumbnailPath(), chromeCastVideoURL, null);
|
chromeCast.setRequestTimeout(120000);
|
||||||
//chromeCast.send( app.namespaces.get(app.namespaces.size()-1).name, new DashCastRequest(chromeCastVideoURL, true, false, 0));
|
chromeCast.load(peertube.getTitle(), null, chromeCastVideoURL, mime);
|
||||||
|
chromeCast.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (IOException | GeneralSecurityException e) {
|
} catch (IOException | GeneralSecurityException e) {
|
||||||
@ -1341,7 +1338,7 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
|
|||||||
if (torrentStream != null && torrentStream.isStreaming()) {
|
if (torrentStream != null && torrentStream.isStreaming()) {
|
||||||
torrentStream.stopStream();
|
torrentStream.stopStream();
|
||||||
}
|
}
|
||||||
if (chromeCast != null) {
|
if (chromeCast != null && chromeCast.isConnected()) {
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
chromeCast.disconnect();
|
chromeCast.disconnect();
|
||||||
|
@ -13,6 +13,7 @@ import androidx.annotation.NonNull;
|
|||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.core.content.res.ResourcesCompat;
|
import androidx.core.content.res.ResourcesCompat;
|
||||||
import androidx.fragment.app.FragmentActivity;
|
import androidx.fragment.app.FragmentActivity;
|
||||||
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||||
import androidx.preference.ListPreference;
|
import androidx.preference.ListPreference;
|
||||||
import androidx.preference.MultiSelectListPreference;
|
import androidx.preference.MultiSelectListPreference;
|
||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
@ -174,7 +175,10 @@ public class SettingsFragment extends PreferenceFragmentCompat implements Shared
|
|||||||
editor.putInt(Helper.SET_VIDEO_CACHE, progress * 10);
|
editor.putInt(Helper.SET_VIDEO_CACHE, progress * 10);
|
||||||
}
|
}
|
||||||
if (key.compareTo(getString(R.string.set_video_minimize_choice)) == 0) {
|
if (key.compareTo(getString(R.string.set_video_minimize_choice)) == 0) {
|
||||||
SwitchPreference set_video_minimize_choice = findPreference(getString(R.string.set_video_minimize_choice));
|
SwitchPreference set_video_minimize_choice = findPreference(
|
||||||
|
|
||||||
|
|
||||||
|
getString(R.string.set_video_minimize_choice));
|
||||||
assert set_video_minimize_choice != null;
|
assert set_video_minimize_choice != null;
|
||||||
editor.putBoolean(getString(R.string.set_video_minimize_choice), set_video_minimize_choice.isChecked());
|
editor.putBoolean(getString(R.string.set_video_minimize_choice), set_video_minimize_choice.isChecked());
|
||||||
}
|
}
|
||||||
@ -229,6 +233,16 @@ public class SettingsFragment extends PreferenceFragmentCompat implements Shared
|
|||||||
Intent intent = new Intent(getActivity(), MainActivity.class);
|
Intent intent = new Intent(getActivity(), MainActivity.class);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
}
|
}
|
||||||
|
if (key.compareTo(getString(R.string.set_cast_choice)) == 0) {
|
||||||
|
SwitchPreference set_cast_choice = findPreference(getString(R.string.set_cast_choice));
|
||||||
|
assert set_cast_choice != null;
|
||||||
|
editor.putBoolean(getString(R.string.set_cast_choice), set_cast_choice.isChecked());
|
||||||
|
Intent intentBC = new Intent(Helper.RECEIVE_CAST_SETTINGS);
|
||||||
|
Bundle b = new Bundle();
|
||||||
|
b.putBoolean("state_asked", set_cast_choice.isChecked());
|
||||||
|
intentBC.putExtras(b);
|
||||||
|
LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(intentBC);
|
||||||
|
}
|
||||||
if (key.compareTo(getString(R.string.set_video_language_choice)) == 0) {
|
if (key.compareTo(getString(R.string.set_video_language_choice)) == 0) {
|
||||||
MultiSelectListPreference set_video_language_choice = findPreference(getString(R.string.set_video_language_choice));
|
MultiSelectListPreference set_video_language_choice = findPreference(getString(R.string.set_video_language_choice));
|
||||||
assert set_video_language_choice != null;
|
assert set_video_language_choice != null;
|
||||||
@ -392,6 +406,12 @@ public class SettingsFragment extends PreferenceFragmentCompat implements Shared
|
|||||||
assert set_video_in_list_choice != null;
|
assert set_video_in_list_choice != null;
|
||||||
set_video_in_list_choice.setChecked(videosInList);
|
set_video_in_list_choice.setChecked(videosInList);
|
||||||
|
|
||||||
|
//****** Allow Chromecast *******
|
||||||
|
boolean cast = sharedpref.getBoolean(getString(R.string.set_cast), false);
|
||||||
|
SwitchPreference set_cast_choice = findPreference(getString(R.string.set_cast_choice));
|
||||||
|
assert set_cast_choice != null;
|
||||||
|
set_cast_choice.setChecked(cast);
|
||||||
|
|
||||||
//****** Language filter *********
|
//****** Language filter *********
|
||||||
LinkedHashMap<String, String> languages = new LinkedHashMap<>(Helper.peertubeInformation.getLanguages());
|
LinkedHashMap<String, String> languages = new LinkedHashMap<>(Helper.peertubeInformation.getLanguages());
|
||||||
List<CharSequence> entriesLanguages = new ArrayList<>();
|
List<CharSequence> entriesLanguages = new ArrayList<>();
|
||||||
|
@ -115,6 +115,7 @@ public class Helper {
|
|||||||
public static final String PREF_KEY_OAUTH_TOKEN = "oauth_token";
|
public static final String PREF_KEY_OAUTH_TOKEN = "oauth_token";
|
||||||
public static final Pattern redirectPattern = Pattern.compile("externalAuthToken=(\\w+)&username=([\\w.-]+)");
|
public static final Pattern redirectPattern = Pattern.compile("externalAuthToken=(\\w+)&username=([\\w.-]+)");
|
||||||
public static final String SET_VIDEO_CACHE = "set_video_cache";
|
public static final String SET_VIDEO_CACHE = "set_video_cache";
|
||||||
|
public static final String RECEIVE_CAST_SETTINGS = "receive_cast_settings";
|
||||||
//Proxy
|
//Proxy
|
||||||
public static final String SET_PROXY_ENABLED = "set_proxy_enabled";
|
public static final String SET_PROXY_ENABLED = "set_proxy_enabled";
|
||||||
public static final String SET_PROXY_HOST = "set_proxy_host";
|
public static final String SET_PROXY_HOST = "set_proxy_host";
|
||||||
|
@ -82,5 +82,10 @@
|
|||||||
android:key="@string/set_video_in_list_choice"
|
android:key="@string/set_video_in_list_choice"
|
||||||
android:summary="@string/set_video_in_list_description"
|
android:summary="@string/set_video_in_list_description"
|
||||||
android:title="@string/set_video_in_list" />
|
android:title="@string/set_video_in_list" />
|
||||||
|
<androidx.preference.SwitchPreference
|
||||||
|
android:icon="@drawable/ic_baseline_cast_24"
|
||||||
|
android:key="@string/set_cast_choice"
|
||||||
|
android:summary="@string/set_cast_description"
|
||||||
|
android:title="@string/set_cast" />
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
</androidx.preference.PreferenceScreen>
|
</androidx.preference.PreferenceScreen>
|
Reference in New Issue
Block a user