-
Notifications
You must be signed in to change notification settings - Fork 72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
(Proposal) [#264] media3 integration #266
(Proposal) [#264] media3 integration #266
Conversation
- manifestUrl: 재생을 위한 dash manifest url - thumbnailUrl: 영상의 썸네일 url
- 모든 session에 sample video 추가
core:domain, kotlinx-coroutines-guava, kotlinx-serialization-json 추가
- material-icons-extended 추가
- ServiceScoped로 player와 session을 주입 - player의 listener를 기반으로 playbackState에 재생 상태 정보 저장 - MediaLibraryService를 구현 - LibrarySessionCallback 구현을 위해 MediaItemProvider를 구현. - MediaId는 json을 활용하여 세션, 트랙 뿐만 아니라 태그 등을 자유롭게 표현할 수 있도록 함. - 외부 모듈에 제공하는 player 컨트롤을 하기 위한 PlayerController
- player는 session id를 선택적인 argument로 가진다. - argument, 마지막 재생된 세션, 첫번째 세션 순으로 재생할 session의 id를 찾는다. - PlayerView composable은 실험적인 구현이므로 검증이 더 필요하다. - 추후 플레이어 알림 클릭 시 사용할 deeplink 추가
- 플레이어 알림 클릭 시 player로 이동
Activity 없이 core:playback module의 PlaybackService만으로 지원. ref. https://developer.android.com/training/cars/media/automotive-os
- app-wear-os, feature:wear-main, feature:wear-player, feature:wear-session 모듈 추가 - 각 모듈은 기존 모바일 앱 구현을 동일하게 wear용으로 구성. - wear-main에서는 wear용 compose-navigation을 이용(SwipeDismissableNavHost). 이 때, NavHost에 destination 추가 시, wear용 라이브러리를 사용 해야한다. (함수 이름도 같고, 크래시도 나지 않음) - wear-session feature에서 wear용 compose 라이브러리를 사용하여 wear 맞춤 세션 브라우징 UI를 구현(ScalingLazyColumn, onRotaryScrollEvent) - 플레이어는 wear os에 맞춰 재구현. video 없이 only audio 재생을 하도록 했다. - app-wear-os에서 SessionActivityIntentProviderImpl을 구현 후 주입. 재생 인디케이터 클릭 시 플레이어가 열리도록 함. - wear os player 구현에 필요하여 현재 media item의 title, artist, artworkUri를 PlaybackState에 추가
@laco-dev 안녕하세요. 현재 |
} | ||
return deepLinkPendingIntent | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
질문) 이 class의 목적이 어떻게 될까요?
PendingIntent를 생성하는거라면 exteions 형태로 만들어도 충분할것 같아보입니다.
객체 형태로 만들어져 있어야할 이유가 있을까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
core:playback module에서 MediaLibrarySession.Builder에서 MediaSession 클릭 시 사용자를 이동시키기 위한 setSessionActivity method에 쓰입니다. 각 앱마다 동작이 다르기에 interface를 선언하고 각 앱마다 다른 구현체를 넣어줬습니다.
@@ -12,4 +12,8 @@ interface SessionRepository { | |||
suspend fun getBookmarkedSessionIds(): Flow<Set<String>> | |||
|
|||
suspend fun bookmarkSession(sessionId: String, bookmark: Boolean) | |||
|
|||
fun getCurrentPlayingSessionId(): Flow<String?> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sessionId가 null인 케이스가 있을까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
null인 경우 = 재생을 한번도 안한 상태입니다.
마지막으로 재생된 session id를 data store에 저장합니다.
아래 callback이 불렸을 때 마지막으로 재생하던 미디어를 재생 시키는 구현에 사용됩니다. (position은 저장 안해둠)
약식으로 대응해뒀는데 값이 null일 땐 keynote를 재생하도록 했습니다.
https://developer.android.com/guide/topics/media/session/mediasession#resumption
suspend operator fun invoke(): String? { | ||
return sessionRepository.getCurrentPlayingSessionId().firstOrNull() | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NotNull 형태로 던져도 괜찮지 않을까 싶네요.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 comment와 함께 고려했을 때, 아무것도 재생하지 않은 상태를 NonNull로 표현할 수 있을까요? 공백? 사실 명확하게 하고자 typing을 하려고 했었는데 .. ㅎㅎ
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GetCurrentPlayingSessionUseCase
이라는 유즈케이스 이름과 반환하는 값으로 볼때 무엇을 반환하는지 잘 예측이 안되지 않을까요?
앞선 non-null 타입을 고려한다명 명확한 타입을 정의하는것도 괜찮아 보입니다.
...main/java/com/droidknights/app2023/core/domain/usecase/UpdateCurrentPlayingSessionUseCase.kt
Outdated
Show resolved
Hide resolved
...playback/src/main/kotlin/com/droidknights/app2023/core/playback/session/MediaItemProvider.kt
Show resolved
Hide resolved
@@ -101,6 +119,7 @@ turbine = { group = "app.cash.turbine", name = "turbine", version.ref = "turbine | |||
|
|||
coroutines-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "coroutine" } | |||
coroutines-android = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-android", version.ref = "coroutine" } | |||
coroutines-guava = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-guava", version.ref = "coroutine" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NOTE: ListenableFuture
와 coroutine을 함께 쓸 수 있도록 추가했습니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
내용이 많아서 아직 모든 부분을 확인하지는 못했습니다. 😭
행사 Session과 미디어 Session이 이름이 중복되서 헷갈리는 상황이 많이 왔는데 이 이름이 일반적으로 미디어쪽의 세션이라고생각하는 상황이 많을까요?
app-automotive/src/main/kotlin/com/droidknights/app2023/automotive/di/AndroidModule.kt
Outdated
Show resolved
Hide resolved
core/data/src/main/java/com/droidknights/app2023/core/data/api/model/VideoResponse.kt
Show resolved
Hide resolved
core/data/src/main/java/com/droidknights/app2023/core/data/mapper/SessionMapper.kt
Outdated
Show resolved
Hide resolved
suspend operator fun invoke(): String? { | ||
return sessionRepository.getCurrentPlayingSessionId().firstOrNull() | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GetCurrentPlayingSessionUseCase
이라는 유즈케이스 이름과 반환하는 값으로 볼때 무엇을 반환하는지 잘 예측이 안되지 않을까요?
앞선 non-null 타입을 고려한다명 명확한 타입을 정의하는것도 괜찮아 보입니다.
core/playback/src/main/kotlin/com/droidknights/app2023/core/playback/PlayerController.kt
Show resolved
Hide resolved
core/playback/src/main/kotlin/com/droidknights/app2023/core/playback/PlayerController.kt
Outdated
Show resolved
Hide resolved
core/playback/src/main/kotlin/com/droidknights/app2023/core/playback/PlayerController.kt
Outdated
Show resolved
Hide resolved
...ck/src/main/kotlin/com/droidknights/app2023/core/playback/playstate/PlaybackStateListener.kt
Outdated
Show resolved
Hide resolved
...ack/src/main/kotlin/com/droidknights/app2023/core/playback/playstate/PlaybackStateManager.kt
Show resolved
Hide resolved
안녕하세요. 상세한 리뷰 감사드립니다. 발표를 위해 구현했던 사항을 한번에 보내 pr이 너무 커지게 된 점 죄송합니다. pr overview에 남겨둔 방향으로 접근하시면 좀 더 용이한 리뷰가...🥲🥲🥲 미디어 Session으로 쓰이는 이름들은 보통 Player를 초기화 하는 쪽에서만 쓰이고 나머지는 행사 Session으로 봐주시면 됩니다. 저도 오랜만에 보니깐 충분히 헷갈릴 만한 상황 같네요. Session이라는 이름이 겹치는 이번 프로젝트에 한해서는 import alias 등으로 명확히 MediaSession* 이란 접두사를 붙여볼 수도 있을 것 같네요. 리뷰 달아주신 사항들은 개별로 커멘트 남기겠습니다. |
- PlaybackPreferencesDataSource를 interface로 분리 - SessionRepository method rename 및 return type 변경
안녕하세요. @laco-dev
더불어, 현재 json file을 이용하여 api 구현을 해두었기 때문에 pr을 그대로 빌드하면 Video 정보가 조회되지 않아 재생을 할 수 없습니다. 혹시 동작을 확인하시고자 한다면 // GithubRawApi.kt
// 변경 전
@GET("/droidknights/DroidKnights2023_App/reference-media3/core/data/src/main/assets/sessions.json")
// 변경 후
@GET("/workspace/DroidKnights2023-app-with-media3/media3/core/data/src/main/assets/sessions.json" 또한, 몇가지 업데이트가 추가될 수 있는데, 이건 그냥 제 folk에서 계속 업데이트 하게될 것 같습니다. 혹시 #265 를 작업하신다면 제 folk repository(https://github.com/workspace/DroidKnights2023-app-with-media3) 도 병기해주시면 감사하겠습니다! |
request endpoint를 folk repository url로 변경
머지합니다. |
Issue
Overview
라이브러리 업그레이드
tv, wear-os, automotive app overview
tv, wear-os, automotive feature overview
core:playback overview
발표자료
+) 원래 media3 구현에 맞춰 개인 repo에 가지고 있으려던 것인지라 에잇! 하며 허술한 부분이 있을 수 있습니다. 개선 방향 제시해주시면 감사하게 반영해보겠습니다 ㅎㅎ