mirror of
git://f0xx.org/android_cast
synced 2026-07-29 05:58:14 +03:00
snap
This commit is contained in:
@@ -143,7 +143,6 @@ public class ReceiverCastService extends Service {
|
|||||||
|
|
||||||
private void restartListening(String pin) {
|
private void restartListening(String pin) {
|
||||||
stopSessionOnly();
|
stopSessionOnly();
|
||||||
closePlaybackUi();
|
|
||||||
resetStreamState();
|
resetStreamState();
|
||||||
phase = Phase.LISTENING;
|
phase = Phase.LISTENING;
|
||||||
acquireWakeLock();
|
acquireWakeLock();
|
||||||
@@ -233,15 +232,16 @@ public class ReceiverCastService extends Service {
|
|||||||
});
|
});
|
||||||
session.start();
|
session.start();
|
||||||
updateStatus(getString(R.string.receiver_ready, pin, settings.getTransport().toUpperCase()));
|
updateStatus(getString(R.string.receiver_ready, pin, settings.getTransport().toUpperCase()));
|
||||||
|
openPlaybackAwaiting(R.string.playback_listening);
|
||||||
Log.i(TAG, "Listening PIN=" + pin + " audio=" + allowIncomingAudio);
|
Log.i(TAG, "Listening PIN=" + pin + " audio=" + allowIncomingAudio);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onSenderConnected(String senderName) {
|
private void onSenderConnected(String senderName) {
|
||||||
phase = Phase.CONNECTED;
|
phase = Phase.CONNECTED;
|
||||||
audioAccepted = null;
|
audioAccepted = null;
|
||||||
playbackLaunched = false;
|
|
||||||
updateStatus(getString(R.string.casting_from, senderName));
|
updateStatus(getString(R.string.casting_from, senderName));
|
||||||
broadcastAuthenticated(senderName);
|
broadcastAuthenticated(senderName);
|
||||||
|
openPlaybackAwaiting(R.string.playback_awaiting_stream);
|
||||||
Log.i(TAG, "Sender connected: " + senderName);
|
Log.i(TAG, "Sender connected: " + senderName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,15 +250,16 @@ public class ReceiverCastService extends Service {
|
|||||||
audioAccepted = null;
|
audioAccepted = null;
|
||||||
hasPendingConfig = false;
|
hasPendingConfig = false;
|
||||||
awaitingKeyframe = true;
|
awaitingKeyframe = true;
|
||||||
|
resetDecoderState();
|
||||||
detachSurfaceOnly();
|
detachSurfaceOnly();
|
||||||
broadcastDisconnected();
|
broadcastDisconnected();
|
||||||
|
openPlaybackAwaiting(R.string.playback_stream_lost);
|
||||||
updateStatus(getString(R.string.waiting_sender));
|
updateStatus(getString(R.string.waiting_sender));
|
||||||
Log.i(TAG, "Sender disconnected");
|
Log.i(TAG, "Sender disconnected");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resetStreamState() {
|
private void resetStreamState() {
|
||||||
hasPendingConfig = false;
|
hasPendingConfig = false;
|
||||||
playbackLaunched = false;
|
|
||||||
awaitingKeyframe = true;
|
awaitingKeyframe = true;
|
||||||
pendingWidth = 0;
|
pendingWidth = 0;
|
||||||
pendingHeight = 0;
|
pendingHeight = 0;
|
||||||
@@ -328,26 +329,28 @@ public class ReceiverCastService extends Service {
|
|||||||
hasPendingConfig = true;
|
hasPendingConfig = true;
|
||||||
decoderActive = false;
|
decoderActive = false;
|
||||||
mainHandler.postDelayed(() -> awaitingKeyframe = false, 2000);
|
mainHandler.postDelayed(() -> awaitingKeyframe = false, 2000);
|
||||||
if (!playbackLaunched) {
|
notifyPlaybackDimensions(pendingWidth, pendingHeight);
|
||||||
playbackLaunched = true;
|
|
||||||
launchPlaybackActivity(pendingWidth, pendingHeight);
|
|
||||||
} else {
|
|
||||||
notifyPlaybackDimensions(pendingWidth, pendingHeight);
|
|
||||||
}
|
|
||||||
tryConfigureDecoder();
|
tryConfigureDecoder();
|
||||||
reconfiguring = false;
|
reconfiguring = false;
|
||||||
Log.i(TAG, "Stream config " + pendingWidth + "x" + pendingHeight);
|
Log.i(TAG, "Stream config " + pendingWidth + "x" + pendingHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void launchPlaybackActivity(int width, int height) {
|
/** Opens or refreshes fullscreen UI with robot overlay (listening / waiting for stream). */
|
||||||
|
private void openPlaybackAwaiting(int messageResId) {
|
||||||
|
playbackLaunched = true;
|
||||||
|
Intent intent = new Intent(this, ReceiverPlaybackActivity.class);
|
||||||
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||||
|
intent.putExtra(ReceiverPlaybackActivity.EXTRA_SHOW_AWAITING, true);
|
||||||
|
intent.putExtra(ReceiverPlaybackActivity.EXTRA_AWAITING_MESSAGE, messageResId);
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void notifyPlaybackDimensions(int width, int height) {
|
||||||
Intent intent = new Intent(this, ReceiverPlaybackActivity.class);
|
Intent intent = new Intent(this, ReceiverPlaybackActivity.class);
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||||
intent.putExtra(ReceiverPlaybackActivity.EXTRA_WIDTH, width);
|
intent.putExtra(ReceiverPlaybackActivity.EXTRA_WIDTH, width);
|
||||||
intent.putExtra(ReceiverPlaybackActivity.EXTRA_HEIGHT, height);
|
intent.putExtra(ReceiverPlaybackActivity.EXTRA_HEIGHT, height);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
}
|
|
||||||
|
|
||||||
private void notifyPlaybackDimensions(int width, int height) {
|
|
||||||
broadcastStreamStarted(width, height);
|
broadcastStreamStarted(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -510,6 +513,7 @@ public class ReceiverCastService extends Service {
|
|||||||
private void releaseAll() {
|
private void releaseAll() {
|
||||||
phase = Phase.IDLE;
|
phase = Phase.IDLE;
|
||||||
resetStreamState();
|
resetStreamState();
|
||||||
|
playbackLaunched = false;
|
||||||
audioAccepted = null;
|
audioAccepted = null;
|
||||||
stopSessionOnly();
|
stopSessionOnly();
|
||||||
closePlaybackUi();
|
closePlaybackUi();
|
||||||
|
|||||||
@@ -23,11 +23,16 @@ import com.foxx.androidcast.ICastStatusCallback;
|
|||||||
import com.foxx.androidcast.R;
|
import com.foxx.androidcast.R;
|
||||||
import com.foxx.androidcast.ui.AspectRatioFrameLayout;
|
import com.foxx.androidcast.ui.AspectRatioFrameLayout;
|
||||||
|
|
||||||
/** Fullscreen video playback — robot overlay while waiting or after stream loss. */
|
/**
|
||||||
|
* Fullscreen display: dancing-robot overlay while listening / waiting;
|
||||||
|
* video surface shown only after the first decoded frame.
|
||||||
|
*/
|
||||||
public class ReceiverPlaybackActivity extends AppCompatActivity implements SurfaceHolder.Callback {
|
public class ReceiverPlaybackActivity extends AppCompatActivity implements SurfaceHolder.Callback {
|
||||||
public static final String EXTRA_WIDTH = "video_width";
|
public static final String EXTRA_WIDTH = "video_width";
|
||||||
public static final String EXTRA_HEIGHT = "video_height";
|
public static final String EXTRA_HEIGHT = "video_height";
|
||||||
public static final String EXTRA_FINISH = "finish_playback";
|
public static final String EXTRA_FINISH = "finish_playback";
|
||||||
|
public static final String EXTRA_SHOW_AWAITING = "show_awaiting";
|
||||||
|
public static final String EXTRA_AWAITING_MESSAGE = "awaiting_message";
|
||||||
|
|
||||||
private AspectRatioFrameLayout aspectContainer;
|
private AspectRatioFrameLayout aspectContainer;
|
||||||
private SurfaceView surfaceView;
|
private SurfaceView surfaceView;
|
||||||
@@ -46,13 +51,7 @@ public class ReceiverPlaybackActivity extends AppCompatActivity implements Surfa
|
|||||||
|
|
||||||
private final ICastStatusCallback.Stub statusCallback = new ICastStatusCallback.Stub() {
|
private final ICastStatusCallback.Stub statusCallback = new ICastStatusCallback.Stub() {
|
||||||
@Override
|
@Override
|
||||||
public void onStatus(String status) {
|
public void onStatus(String status) {}
|
||||||
runOnUiThread(() -> {
|
|
||||||
if (status != null && status.toLowerCase().contains("waiting")) {
|
|
||||||
showAwaitingOverlay(R.string.playback_awaiting_stream);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAuthenticated(String senderName) {
|
public void onAuthenticated(String senderName) {
|
||||||
@@ -85,10 +84,6 @@ public class ReceiverPlaybackActivity extends AppCompatActivity implements Surfa
|
|||||||
bound = true;
|
bound = true;
|
||||||
try {
|
try {
|
||||||
receiverService.registerCallback(statusCallback);
|
receiverService.registerCallback(statusCallback);
|
||||||
String status = receiverService.getStatus();
|
|
||||||
if (status != null && status.toLowerCase().contains("waiting")) {
|
|
||||||
showAwaitingOverlay(R.string.playback_awaiting_stream);
|
|
||||||
}
|
|
||||||
} catch (RemoteException ignored) {
|
} catch (RemoteException ignored) {
|
||||||
}
|
}
|
||||||
attachSurfaceIfReady();
|
attachSurfaceIfReady();
|
||||||
@@ -119,9 +114,14 @@ public class ReceiverPlaybackActivity extends AppCompatActivity implements Surfa
|
|||||||
awaitingMessage = findViewById(R.id.text_awaiting_message);
|
awaitingMessage = findViewById(R.id.text_awaiting_message);
|
||||||
surfaceHolder = surfaceView.getHolder();
|
surfaceHolder = surfaceView.getHolder();
|
||||||
surfaceHolder.addCallback(this);
|
surfaceHolder.addCallback(this);
|
||||||
|
surfaceView.setZOrderMediaOverlay(false);
|
||||||
robotDance = AnimationUtils.loadAnimation(this, R.anim.robot_dance);
|
robotDance = AnimationUtils.loadAnimation(this, R.anim.robot_dance);
|
||||||
applyAspectRatio();
|
applyAspectRatio();
|
||||||
showAwaitingOverlay(R.string.playback_awaiting_stream);
|
|
||||||
|
if (getIntent().getBooleanExtra(EXTRA_SHOW_AWAITING, true)) {
|
||||||
|
int msg = getIntent().getIntExtra(EXTRA_AWAITING_MESSAGE, R.string.playback_listening);
|
||||||
|
showAwaitingOverlay(msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -133,8 +133,9 @@ public class ReceiverPlaybackActivity extends AppCompatActivity implements Surfa
|
|||||||
}
|
}
|
||||||
readSizeFromIntent(intent);
|
readSizeFromIntent(intent);
|
||||||
updateVideoSize(videoWidth, videoHeight);
|
updateVideoSize(videoWidth, videoHeight);
|
||||||
if (!streamRendering) {
|
if (intent.getBooleanExtra(EXTRA_SHOW_AWAITING, false)) {
|
||||||
showAwaitingOverlay(R.string.playback_awaiting_stream);
|
int msg = intent.getIntExtra(EXTRA_AWAITING_MESSAGE, R.string.playback_listening);
|
||||||
|
showAwaitingOverlay(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,7 +199,11 @@ public class ReceiverPlaybackActivity extends AppCompatActivity implements Surfa
|
|||||||
if (awaitingOverlay == null) {
|
if (awaitingOverlay == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (surfaceView != null) {
|
||||||
|
surfaceView.setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
awaitingOverlay.setVisibility(View.VISIBLE);
|
awaitingOverlay.setVisibility(View.VISIBLE);
|
||||||
|
awaitingOverlay.bringToFront();
|
||||||
if (awaitingMessage != null) {
|
if (awaitingMessage != null) {
|
||||||
awaitingMessage.setText(messageResId);
|
awaitingMessage.setText(messageResId);
|
||||||
}
|
}
|
||||||
@@ -206,10 +211,12 @@ public class ReceiverPlaybackActivity extends AppCompatActivity implements Surfa
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void hideAwaitingOverlay() {
|
private void hideAwaitingOverlay() {
|
||||||
if (awaitingOverlay == null) {
|
if (awaitingOverlay != null) {
|
||||||
return;
|
awaitingOverlay.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
if (surfaceView != null) {
|
||||||
|
surfaceView.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
awaitingOverlay.setVisibility(View.GONE);
|
|
||||||
stopRobotAnimation();
|
stopRobotAnimation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="#CC000000"
|
android:background="#CC000000"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
|
android:elevation="16dp"
|
||||||
android:focusable="true">
|
android:focusable="true">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
<string name="label_receiver_audio">Play incoming cast audio on this device</string>
|
<string name="label_receiver_audio">Play incoming cast audio on this device</string>
|
||||||
<string name="start_receiver">Start listening (keeps running in background)</string>
|
<string name="start_receiver">Start listening (keeps running in background)</string>
|
||||||
<string name="playback_buffering">Connected — waiting for video…</string>
|
<string name="playback_buffering">Connected — waiting for video…</string>
|
||||||
|
<string name="playback_listening">Listening for cast — awaiting sender…</string>
|
||||||
<string name="playback_awaiting_stream">Awaiting for stream to come…</string>
|
<string name="playback_awaiting_stream">Awaiting for stream to come…</string>
|
||||||
<string name="playback_stream_lost">Stream lost — awaiting for stream to come…</string>
|
<string name="playback_stream_lost">Stream lost — awaiting for stream to come…</string>
|
||||||
<string name="receiver_starting">Starting receiver service…</string>
|
<string name="receiver_starting">Starting receiver service…</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user