Files
memby/app/src/main/res/layout/activity_player.xml
T

186 lines
7.9 KiB
XML
Raw Normal View History

2026-07-29 15:26:40 +12:00
<?xml version="1.0" encoding="utf-8"?>
<!-- <merge> rather than a FrameLayout root: setContentView already gives us a full-screen
FrameLayout to merge into, so this saves a redundant level in the view hierarchy. -->
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.media3.ui.PlayerView
android:id="@+id/player_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
app:auto_show="true"
app:controller_layout_id="@layout/memby_player_controls"
app:hide_on_touch="true"
app:keep_content_on_player_reset="true"
app:resize_mode="fit"
app:show_buffering="never"
app:surface_type="surface_view"
app:use_controller="true" />
2026-08-02 22:10:19 +12:00
<!-- Channel + programme identity. It is owned by the activity rather than the
controller, so it can appear briefly without opening the transport controls. -->
<include layout="@layout/player_playback_identity" />
<!-- The ten-minute cue. Declared before the next-up banner so that banner covers it
if the two ever coincide: what comes next matters more than how long is left. -->
<include layout="@layout/player_time_remaining" />
<!-- Finale context has priority over the ordinary start cue and is physically stacked
above it. Both remain non-focusable lower thirds. -->
<include layout="@layout/player_season_finale" />
2026-07-29 15:26:40 +12:00
<!-- Above the video, below the loading overlay: a slide that is still starting has
nothing to say about what comes next. -->
<include layout="@layout/player_next_up_banner" />
<!-- App-owned subtitle controls. ExoPlayer supplies tracks and rendering only; this
overlay deliberately stays in Memby's TV design language. -->
<include layout="@layout/player_subtitle_overlay" />
<!-- Cast is metadata-only and never pauses or rebuilds the player. -->
<include layout="@layout/player_cast_overlay" />
2026-08-02 22:10:19 +12:00
<!-- Service alerts, the same bar the launcher shows. Declared before the loading and
error overlays so those cover it: a notice about the library is not what someone
staring at a failed stream needs. Never focusable, so it cannot take the remote
away from the transport controls. -->
<androidx.compose.ui.platform.ComposeView
android:id="@+id/player_service_alerts"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:focusable="false" />
2026-07-29 15:26:40 +12:00
<LinearLayout
android:id="@+id/playback_loading"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#F2050708"
android:focusable="false"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/playback_loading_logo"
android:layout_width="82dp"
android:layout_height="70dp"
android:contentDescription="@string/playback_loading"
android:scaleType="fitCenter"
android:src="@drawable/emby_logo" />
<TextView
android:id="@+id/playback_loading_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="18dp"
android:text="@string/playback_loading"
android:textColor="#FFFFFFFF"
android:textSize="20sp"
android:textStyle="bold" />
<TextView
android:id="@+id/playback_loading_hint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="7dp"
android:text="@string/playback_loading_hint"
android:textColor="#FF929AA0"
android:textSize="14sp" />
</LinearLayout>
2026-08-02 22:10:19 +12:00
<!-- The existing PlayerView is temporarily hosted inside this overlay, then returned
here at full-screen size after the countdown. No second player or stream is used. -->
2026-07-29 15:26:40 +12:00
<include layout="@layout/player_preroll" />
<!-- Deliberately outside PlayerView's controller hierarchy: a fatal error must remain
actionable after Media3 hides its transport controls. -->
<FrameLayout
android:id="@+id/playback_error"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#F2050708"
android:focusable="false"
android:visibility="gone">
<LinearLayout
android:layout_width="600dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center_horizontal"
android:orientation="vertical"
android:padding="36dp">
<ImageView
android:layout_width="72dp"
android:layout_height="62dp"
android:contentDescription="@null"
android:scaleType="fitCenter"
android:src="@drawable/emby_logo" />
<TextView
android:id="@+id/playback_error_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:gravity="center"
android:textColor="#FFFFFFFF"
android:textSize="28sp"
android:textStyle="bold" />
<TextView
android:id="@+id/playback_error_detail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center"
android:lineSpacingExtra="3dp"
android:textColor="#BFFFFFFF"
android:textSize="17sp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="28dp"
android:orientation="horizontal">
<Button
android:id="@+id/playback_error_retry"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/next_up_primary_button"
android:focusable="true"
android:minWidth="0dp"
android:paddingStart="28dp"
android:paddingTop="10dp"
android:paddingEnd="28dp"
android:paddingBottom="10dp"
android:stateListAnimator="@null"
android:text="@string/playback_try_again"
android:textAllCaps="false"
android:textColor="@color/next_up_button_text"
android:textSize="16sp" />
<Button
android:id="@+id/playback_error_exit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:background="@drawable/next_up_secondary_button"
android:focusable="true"
android:minWidth="0dp"
android:paddingStart="28dp"
android:paddingTop="10dp"
android:paddingEnd="28dp"
android:paddingBottom="10dp"
android:stateListAnimator="@null"
android:text="@string/playback_back_to_memby"
android:textAllCaps="false"
android:textColor="@color/next_up_button_text"
android:textSize="16sp" />
</LinearLayout>
</LinearLayout>
</FrameLayout>
</merge>