Skip to content

New video page with media3 based player from pipepipex#46

Closed
InfinityLoop1308 wants to merge 14 commits into
devfrom
new-video-page-with-media3
Closed

New video page with media3 based player from pipepipex#46
InfinityLoop1308 wants to merge 14 commits into
devfrom
new-video-page-with-media3

Conversation

@InfinityLoop1308
Copy link
Copy Markdown
Owner

@InfinityLoop1308 InfinityLoop1308 commented Jun 5, 2026

(experimental) a very aggressive refactor, targeting to replace the whole player & mediaservice & videodetailfragement with there equivalents in ppx. still wip and waiting for codex 5 hour limit. haven't done any test.

issues of the current codebase:

  • upgrading targeting sdk 35 forces the app edge-to-edge, causing layout issue on VideoDetailFragment, and seems can't be solved easily
  • player.java and VideoDetailFragment.java are too big to refactor or maintain; playerservice also uses many tricks
  • mediaservice have some weird sync bugs for long, and exoplayer is also deprecated.

doing the refactor can help simplify the codebase and remove tech debt. but the consideration here is: none of the reasons are essential enough.

I'll going to see if codex is able to achieve a roughly-work stage. if not it seems better to abort the pr and go #45


(below gen by codex)

Purpose

Introduce an experimental Media3 and Compose-based video detail/player implementation while
retaining the existing player as a fallback.

The existing Use beta UI setting selects the implementation:

  • Disabled: use the existing video detail and player.
  • Enabled: use the new Compose video detail page and Media3 playback stack.

This allows incremental migration and real-world testing before removing the legacy player.

Impact Scope

  • Video detail page and mini-player hosting
  • Main, background, and popup playback
  • Playback service and Media3 session
  • Playback queue, shuffle, and enqueue behavior
  • Media button, timestamp, and Android Auto routing
  • YouTube, BiliBili, and NicoNico media sources
  • Existing Use beta UI setting behavior

The legacy implementation remains unchanged and available when the beta UI setting is
disabled.

Completed

  • Added an independent top-level ComposeView host for the new video detail page.

  • Added a Media3 playback service, controller abstraction, shared playback state, and queue
    manager.

  • Routed main player, background player, popup player, enqueue, enqueue-next, and shuffle
    actions to Media3 when beta UI is enabled.

  • Prevented experimental playback paths from accidentally starting the legacy player.

  • Routed media buttons, timestamp links, and car connection events to the selected
    implementation.

  • Added an initial Compose video detail page with:

    • Video playback and pause controls
    • Detail, bottom-player, and fullscreen states
    • Non-following vertical swipe transitions
    • Title, uploader, view count, description, and related items
    • Internal related-item navigation and back stack
  • Added a Media3 popup player while reusing the existing popup window behavior:

    • WindowManager integration
    • Position and size settings
    • Dragging, resizing, and close-target behavior
  • Added Media3 source handling for:

    • Progressive, DASH, and HLS streams
    • Separate video and audio stream merging
    • BiliBili Referer requirements
    • NicoNico on-demand Cookie requirements
    • YouTube separated progressive streams
    • YouTube OTF DASH streams
    • YouTube post-live DVR streams
  • Fixed queue synchronization, shuffle behavior, enqueue-next ordering, and playback mode
    switching.

  • Confirmed that assembleDebug builds successfully.

Not Yet Completed

  • Full video detail functionality:

    • Comments and replies
    • Danmaku
    • SponsorBlock
    • Complete description link handling
    • Share, download, bookmark, subscription, and history actions
  • Complete player controls:

    • Seek bar and seek actions
    • Resolution, subtitle, and audio-track selection
    • Playback speed, repeat mode, and queue UI
    • Error presentation and retry controls
  • Fullscreen behavior:

    • Orientation handling based on video dimensions and system auto-rotate settings
    • System bar handling
    • Tablet, TV, and multi-window adaptation
  • Popup playback control UI.

  • YouTube-specific Media3 HTTP handling for range/rn parameters and expired URL refresh.

  • NicoNico live WebSocket/HLS handling.

  • Complete notification, lock-screen control, Android Auto, service lifecycle, and process
    restoration behavior.

  • Device-level playback regression testing for YouTube, BiliBili, and NicoNico.

  • Removal of the legacy player after the experimental implementation reaches feature parity.


Copilot AI review requested due to automatic review settings June 5, 2026 10:33
@InfinityLoop1308 InfinityLoop1308 changed the title New video page with media3 based player from rinox New video page with media3 based player from pipepipex Jun 5, 2026
@InfinityLoop1308 InfinityLoop1308 marked this pull request as draft June 5, 2026 10:38
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces an experimental, opt-in (via “Use beta UI”) video detail page built with Jetpack Compose plus a new Media3-based playback stack, while preserving the existing (legacy) player path when the setting is disabled.

Changes:

  • Adds a Compose-hosted video detail screen and a lightweight state/viewmodel layer to drive it.
  • Introduces a new Media3 PlaybackService, controller abstraction, queue manager, and media source factory for extractor-backed playback.
  • Routes key playback/navigation entry points (main/background/popup/enqueue/timestamps) to the experimental stack when enabled.

Reviewed changes

Copilot reviewed 27 out of 27 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
app/src/main/res/layout/activity_main.xml Adds a hidden ComposeView host for the experimental video detail UI.
app/src/main/java/project/pipepipe/app/viewmodel/VideoDetailViewModel.kt New viewmodel-like state holder for experimental video detail navigation/loading.
app/src/main/java/project/pipepipe/app/uistate/VideoDetailUiState.kt Defines experimental video detail UI state container.
app/src/main/java/project/pipepipe/app/uistate/VideoDetailPageState.kt Defines page-state enum (hidden/bottom/detail/fullscreen).
app/src/main/java/project/pipepipe/app/ui/screens/videodetail/VideoDetailScreen.kt Compose implementation of the experimental video detail + embedded PlayerView.
app/src/main/java/project/pipepipe/app/ui/ExperimentalVideoDetailHost.kt Binds the Compose host to MainActivity and bridges navigation/back handling.
app/src/main/java/project/pipepipe/app/SharedContext.kt Adds shared controller/queue/playback-mode plumbing for the experimental stack.
app/src/main/java/project/pipepipe/app/service/PlaybackService.kt New Media3 MediaLibraryService hosting an ExoPlayer + session + popup manager.
app/src/main/java/project/pipepipe/app/QueueManager.kt New queue state + shuffle/unshuffle + sync hooks to controller.
app/src/main/java/project/pipepipe/app/popup/PopupPlayerManager.kt Media3-based popup player window manager integration.
app/src/main/java/project/pipepipe/app/PlaybackMode.kt Experimental playback mode enum (video/audio/popup).
app/src/main/java/project/pipepipe/app/platform/PlatformMediaItem.kt Platform-agnostic media item model for the experimental controller layer.
app/src/main/java/project/pipepipe/app/platform/PlatformMediaController.kt Controller interface + playback/track selection abstractions for experimental stack.
app/src/main/java/project/pipepipe/app/platform/AndroidMediaController.kt Media3-backed implementation of PlatformMediaController.
app/src/main/java/project/pipepipe/app/mediasource/StreamInfoRepository.kt In-memory cache for extracted StreamInfo keyed by URL.
app/src/main/java/project/pipepipe/app/mediasource/MediaItemFactory.kt Maps between extractor StreamInfo, platform items, and Media3 MediaItem.
app/src/main/java/project/pipepipe/app/mediasource/ExtractorMediaSourceFactory.kt Media3 MediaSource.Factory that builds sources from extractor stream data.
app/src/main/java/project/pipepipe/app/LegacyPlayQueueAdapter.kt Adapts legacy PlayQueue into the experimental platform item list.
app/src/main/java/project/pipepipe/app/ExperimentalPlaybackRouter.kt Routes play/enqueue/seek actions to experimental service/controller stack.
app/src/main/java/org/schabi/newpipe/util/NavigationHelper.java Switches playback/detail navigation to experimental routing when enabled.
app/src/main/java/org/schabi/newpipe/util/MediaButtonReceiver.java Disables legacy media-button receiver behavior when experimental UI is enabled.
app/src/main/java/org/schabi/newpipe/util/external_communication/TextLinkifier.java Routes timestamp clicks to experimental seek when enabled.
app/src/main/java/org/schabi/newpipe/util/external_communication/InternalUrlsHandler.java Routes internal timestamp URLs to experimental seek when enabled.
app/src/main/java/org/schabi/newpipe/util/CarConnectionStateReceiver.java Stops the experimental service instead of legacy when experimental UI is enabled.
app/src/main/java/org/schabi/newpipe/MainActivity.java Attaches the experimental Compose host and integrates experimental back handling.
app/src/main/AndroidManifest.xml Registers the new experimental PlaybackService.
app/build.gradle Adds Compose BOM usage and adds Media3 dependencies alongside legacy ExoPlayer deps.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +7 to +11
import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.session.MediaLibraryService
import androidx.media3.session.MediaSession
import androidx.preference.PreferenceManager
import project.pipepipe.app.SharedContext
Comment on lines +78 to +86
<service
android:name="project.pipepipe.app.service.PlaybackService"
android:exported="true"
android:foregroundServiceType="mediaPlayback">
<intent-filter>
<action android:name="androidx.media3.session.MediaLibraryService" />
<action android:name="android.media.browse.MediaBrowserService" />
</intent-filter>
</service>

@JvmStatic
fun play(context: Context, queue: PlayQueue, mode: PlaybackMode, shuffle: Boolean) {
context.startService(Intent(context, PlaybackService::class.java))

@JvmStatic
fun enqueue(context: Context, queue: PlayQueue, next: Boolean) {
context.startService(Intent(context, PlaybackService::class.java))
Comment on lines +44 to +53
fun fromMediaItem(item: MediaItem): PlatformMediaItem = PlatformMediaItem(
mediaId = item.mediaId,
title = item.mediaMetadata.title?.toString(),
artist = item.mediaMetadata.artist?.toString(),
artworkUrl = item.mediaMetadata.artworkUri?.toString(),
durationMs = item.mediaMetadata.durationMs,
serviceId = item.mediaMetadata.extras?.getInt(KEY_SERVICE_ID),
uuid = item.mediaMetadata.extras?.getString(KEY_UUID)
?: java.util.UUID.randomUUID().toString()
)
Comment on lines +124 to +130
IconButton(onClick = {
val playbackController = controller ?: return@IconButton
if (playbackController.currentMediaItem.value?.mediaId != streamInfo.url) {
val item = MediaItemFactory.fromStreamInfo(streamInfo)
SharedContext.queueManager.setQueue(listOf(item))
playbackController.prepare()
}
Comment on lines +32 to +44
runCatching {
withContext(Dispatchers.IO) {
ExtractorHelper.getStreamInfo(serviceId, url, false).blockingGet()
}
}.onSuccess {
MediaItemFactory.fromStreamInfo(it)
mutableUiState.value = mutableUiState.value.copy(
streamInfoStack = mutableUiState.value.streamInfoStack + it,
isLoading = false
)
}.onFailure {
mutableUiState.value = mutableUiState.value.copy(isLoading = false, error = it)
}
Comment on lines +66 to +73
mutableQueue.value = mutableQueue.value.toMutableList().apply {
add(to, removeAt(from))
}
backup?.let {
val item = it.removeAt(from)
it.add(to, item)
}
controller?.syncQueueMove(from, to)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants