Skip to content

Commit

Permalink
- working towards getting chromecast to report playback status. does …
Browse files Browse the repository at this point in the history
…not report when playback ends
  • Loading branch information
deHank committed Aug 7, 2023
1 parent a743e55 commit bec792c
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 54 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ class EpisodeBottomSheetFragment : BottomSheetDialogFragment() {
//remoteMediaClient.mediaStatus
}
if (session != null) {
if(session.remoteMediaClient?.isPaused() == true){
if(session.remoteMediaClient?.isPaused == true){
print("yeet")
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.navigation.fragment.findNavController
import com.google.android.gms.cast.framework.CastButtonFactory
import dagger.hilt.android.AndroidEntryPoint
import dev.jdtech.jellyfin.adapters.CollectionListAdapter
import dev.jdtech.jellyfin.databinding.FragmentMediaBinding
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import androidx.navigation.fragment.navArgs
import com.google.android.gms.cast.framework.CastContext
import com.google.android.gms.cast.framework.CastState
import com.google.android.gms.cast.framework.media.RemoteMediaClient
import com.google.android.material.R as MaterialR
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import dev.jdtech.jellyfin.AppPreferences
Expand Down
2 changes: 1 addition & 1 deletion app/phone/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent">

<fragment
<androidx.fragment.app.FragmentContainerView
android:id="@+id/cast_mini_controller"
android:layout_width="match_parent"
android:layout_height="wrap_content"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import androidx.media3.common.MimeTypes
import com.google.android.gms.cast.MediaInfo
import com.google.android.gms.cast.MediaLoadRequestData
import com.google.android.gms.cast.MediaMetadata
import com.google.android.gms.cast.MediaStatus
import com.google.android.gms.cast.MediaTrack
import com.google.android.gms.cast.framework.CastContext
import com.google.android.gms.cast.framework.CastSession
Expand All @@ -33,6 +34,9 @@ import org.jellyfin.sdk.model.api.BaseItemDto
import org.jellyfin.sdk.model.api.ImageType.PRIMARY
import org.jellyfin.sdk.model.api.ItemFields
import org.jellyfin.sdk.model.api.MediaStreamType
import org.jellyfin.sdk.model.api.PlayMethod
import org.jellyfin.sdk.model.api.PlaybackProgressInfo
import org.jellyfin.sdk.model.api.RepeatMode
import timber.log.Timber
import javax.inject.Inject

Expand Down Expand Up @@ -203,40 +207,66 @@ class PlayerViewModel @Inject internal constructor(
data class PlayerItemError(val error: Exception) : PlayerItemState()
data class PlayerItems(val items: List<PlayerItem>) : PlayerItemState()

private fun loadRemoteMedia(
private suspend fun loadRemoteMedia(
position: Int,
mCastSession: CastSession,
mediaInfo: MediaInfo,
streamUrl: String,
item: PlayerItem,
episode: BaseItemDto
) {


if (mCastSession == null) {
return
}

val remoteMediaClient = mCastSession.remoteMediaClient ?: return
var previousSubtitleTrackIds: LongArray? = null
var newIndex = -1
var subtitleIndex = -1
var newAudioIndex = 1

//startProgressUpdates(item)

val callback = object : RemoteMediaClient.Callback() {
override fun onPreloadStatusUpdated() {
print("test")
}

override fun onQueueStatusUpdated() {
print("test")
}

override fun onStatusUpdated() {
val mediaStatus = remoteMediaClient.mediaStatus



if (mediaStatus?.playerState == MediaStatus.PLAYER_STATE_IDLE) {
print("test")
}
// Check if playback is stopped by user
if (mediaStatus?.playerState == MediaStatus.PLAYER_STATE_PAUSED ||
mediaStatus?.playerState == MediaStatus.PLAYER_STATE_LOADING
) {
print("test")
}


val activeSubtitleTrackIds = mediaStatus?.activeTrackIds

val subtitlesOffset =
mediaInfo?.mediaTracks!!.size - item.externalSubtitles.size
val mediaInfo = mediaStatus?.mediaInfo
val externalSubtitleCount = mediaInfo?.textTrackStyle?.describeContents()
mediaInfo.mediaTracks!!.size - item.externalSubtitles.size

if (mediaStatus?.playerState == MediaStatus.PLAYER_STATE_BUFFERING) {
viewModelScope.launch {
startProgressUpdates(item, mediaStatus.streamPosition.toInt())
}
}


if (mediaStatus != null) {
if (previousSubtitleTrackIds != mediaStatus.activeTrackIds && previousSubtitleTrackIds != null) {
if (!previousSubtitleTrackIds.contentEquals(mediaStatus.activeTrackIds) && previousSubtitleTrackIds != null) {
if (activeSubtitleTrackIds != null) {
if (activeSubtitleTrackIds.isNotEmpty()) {


newIndex =
(mediaStatus.activeTrackIds!!.get(0)).toInt()
if (newIndex < subtitlesOffset) {
Expand All @@ -257,7 +287,9 @@ class PlayerViewModel @Inject internal constructor(
.setAutoplay(true)
.setCurrentTime(mediaStatus.streamPosition.toInt().toLong())
.build()

)

}


Expand All @@ -282,10 +314,24 @@ class PlayerViewModel @Inject internal constructor(
)


val mediaStatus = remoteMediaClient.mediaStatus
val activeMediaTracks = mediaStatus?.activeTrackIds



}

private suspend fun startProgressUpdates(item: PlayerItem, position: Int) {
jellyfinApi.playStateApi.reportPlaybackProgress(
data = PlaybackProgressInfo(
canSeek = true,
itemId = item.itemId,
isMuted = false,
isPaused = false,
playMethod = PlayMethod.TRANSCODE,
repeatMode = RepeatMode.REPEAT_NONE,
mediaSourceId = item.mediaSourceId,
positionTicks = position.toLong() * 10000
)
)
}

private fun buildMediaInfo(
Expand All @@ -303,10 +349,10 @@ class PlayerViewModel @Inject internal constructor(
}

if (thumbnailUrl != null) {
var thumbnailImage = WebImage(Uri.parse(thumbnailUrl))
val thumbnailImage = WebImage(Uri.parse(thumbnailUrl))
mediaMetadata.addImage(thumbnailImage)
} else {
var thumbnailImage = WebImage(
val thumbnailImage = WebImage(
Uri.parse(
jellyfinApi.api.imageApi.getItemImageUrl(
item.itemId,
Expand All @@ -322,7 +368,6 @@ class PlayerViewModel @Inject internal constructor(
val mediaSubtitles = episode.mediaStreams?.mapIndexed { index, externalSubtitle ->
MediaTrack.Builder(index.toLong(), MediaTrack.TYPE_TEXT)
.setName(externalSubtitle.displayTitle + " " + externalSubtitle.type)
//.setContentId(jellyfinApi.api.createUrl("/videos/" + item.itemId + "/master.m3u8?DeviceId=" + jellyfinApi.api.deviceInfo.id + "&MediaSourceId=" + item.mediaSourceId + "&VideoCodec=h264,h264&AudioCodec=mp3&AudioStreamIndex=1&SubtitleStreamIndex=" + index + "&VideoBitrate=119872000&AudioBitrate=128000&AudioSampleRate=44100&MaxFramerate=23.976025&PlaySessionId=" + (Math.random() * 10000).toInt() + "&api_key=" + jellyfinApi.api.accessToken + "&SubtitleMethod=Encode&RequireAvc=false&SegmentContainer=ts&BreakOnNonKeyFrames=False&h264-level=40&h264-videobitdepth=8&h264-profile=high&h264-audiochannels=2&aac-profile=lc&TranscodeReasons=SubtitleCodecNotSupported")
.setContentType("text/vtt")
.setLanguage(externalSubtitle.language)
.build()
Expand Down Expand Up @@ -352,7 +397,7 @@ class PlayerViewModel @Inject internal constructor(
if (session != null) {
val mediaInfo = buildMediaInfo(streamUrl, item, episode)

loadRemoteMedia(0, session, mediaInfo, streamUrl, item, episode)
loadRemoteMedia(0, session, mediaInfo, item, episode)

}
} catch (e: Exception) {
Expand Down

0 comments on commit bec792c

Please sign in to comment.