Jellyfin Android TV版音乐专辑收藏功能失效问题分析

Jellyfin Android TV版音乐专辑收藏功能失效问题分析

【免费下载链接】jellyfin-androidtv Android TV Client for Jellyfin 【免费下载链接】jellyfin-androidtv 项目地址: https://gitcode.com/gh_mirrors/je/jellyfin-androidtv

问题背景

在使用Jellyfin Android TV客户端时,许多用户反映音乐专辑收藏功能存在异常:收藏的专辑无法正确显示在"我的收藏"列表中,或者收藏状态无法正常同步。这个问题严重影响了用户的音乐体验,特别是对于那些依赖收藏功能来管理个人音乐库的用户。

技术架构分析

收藏功能核心组件

Jellyfin Android TV版的收藏功能主要涉及以下几个核心组件:

mermaid

API调用流程

收藏功能的完整调用流程如下:

mermaid

问题根因分析

1. API过滤条件问题

ItemListFragmentHelper.ktgetFavoritePlaylist方法中,使用了特定的过滤条件:

api.itemsApi.getItems(
    parentId = parentId,
    includeItemTypes = setOf(BaseItemKind.AUDIO),
    recursive = true,
    filters = setOf(org.jellyfin.sdk.model.api.ItemFilter.IS_FAVORITE_OR_LIKES),
    sortBy = setOf(ItemSortBy.RANDOM),
    limit = 100,
    fields = ItemRepository.itemFields,
)

这里的关键问题是:

  • includeItemTypes = setOf(BaseItemKind.AUDIO) 只包含音频文件,不包含音乐专辑
  • 音乐专辑的类型是BaseItemKind.MUSIC_ALBUM,但查询时被排除在外

2. 数据类型混淆

在Jellyfin的数据模型中,音乐内容存在多种类型:

数据类型BaseItemKind说明
单曲音频AUDIO单个音乐文件
音乐专辑MUSIC_ALBUM专辑容器
播放列表PLAYLIST自定义播放列表

当前的收藏查询只针对AUDIO类型,忽略了MUSIC_ALBUM类型。

3. 收藏状态同步问题

ItemMutationRepositoryImpl.kt中,收藏操作确实执行了API调用:

override suspend fun setFavorite(item: UUID, favorite: Boolean): UserItemDataDto {
    val response by when {
        favorite -> withContext(Dispatchers.IO) { api.userLibraryApi.markFavoriteItem(itemId = item) }
        else -> withContext(Dispatchers.IO) { api.userLibraryApi.unmarkFavoriteItem(itemId = item) }
    }
    dataRefreshService.lastFavoriteUpdate = Instant.now()
    return response
}

但收藏列表查询时没有正确包含专辑类型。

解决方案

方案一:修改查询条件(推荐)

修改ItemListFragmentHelper.kt中的getFavoritePlaylist方法:

fun MusicFavoritesListFragment.getFavoritePlaylist(
    parentId: UUID?,
    callback: (items: List<BaseItemDto>) -> Unit
) {
    val api by inject<ApiClient>()

    lifecycleScope.launch {
        val result = withContext(Dispatchers.IO) {
            api.itemsApi.getItems(
                parentId = parentId,
                includeItemTypes = setOf(BaseItemKind.AUDIO, BaseItemKind.MUSIC_ALBUM),
                recursive = true,
                filters = setOf(org.jellyfin.sdk.model.api.ItemFilter.IS_FAVORITE_OR_LIKES),
                sortBy = setOf(ItemSortBy.RANDOM),
                limit = 100,
                fields = ItemRepository.itemFields,
            ).content
        }

        callback(result.items)
    }
}

方案二:添加专辑专用查询方法

或者创建专门的专辑收藏查询方法:

fun MusicFavoritesListFragment.getFavoriteAlbums(
    parentId: UUID?,
    callback: (items: List<BaseItemDto>) -> Unit
) {
    val api by inject<ApiClient>()

    lifecycleScope.launch {
        val result = withContext(Dispatchers.IO) {
            api.itemsApi.getItems(
                parentId = parentId,
                includeItemTypes = setOf(BaseItemKind.MUSIC_ALBUM),
                recursive = true,
                filters = setOf(org.jellyfin.sdk.model.api.ItemFilter.IS_FAVORITE_OR_LIKES),
                sortBy = setOf(ItemSortBy.ALBUM_ARTIST, ItemSortBy.ALBUM),
                limit = 100,
                fields = ItemRepository.itemFields,
            ).content
        }

        callback(result.items)
    }
}

方案三:界面优化

MusicFavoritesListFragment.java中添加专辑显示支持:

// 添加专辑显示按钮
TextUnderButton albums = TextUnderButton.create(requireContext(), R.drawable.ic_album, 
    Utils.convertDpToPixel(requireContext(), 35), 2, getString(R.string.lbl_albums), 
    new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // 调用专辑收藏查询
            ItemListFragmentHelperKt.getFavoriteAlbums(MusicFavoritesListFragment.this, 
                parentId, itemResponse);
        }
    });
mButtonRow.addView(albums);

测试验证方案

单元测试

@Test
fun testFavoriteAlbumQuery() {
    // 模拟API响应
    val mockResponse = GetItemsResponse(
        items = listOf(
            BaseItemDto(
                id = UUID.randomUUID(),
                name = "Test Album",
                type = BaseItemKind.MUSIC_ALBUM,
                userData = UserItemDataDto(isFavorite = true)
            )
        )
    )
    
    // 验证查询条件包含MUSIC_ALBUM
    verify(api.itemsApi).getItems(
        includeItemTypes = setOf(BaseItemKind.AUDIO, BaseItemKind.MUSIC_ALBUM),
        filters = setOf(ItemFilter.IS_FAVORITE_OR_LIKES)
    )
}

集成测试

  1. 收藏功能测试:收藏一个音乐专辑,验证是否出现在收藏列表
  2. 取消收藏测试:取消收藏,验证是否从列表中移除
  3. 混合内容测试:同时收藏音频和专辑,验证都能正确显示

性能优化建议

查询优化

// 添加缓存机制
private var cachedFavorites: List<BaseItemDto>? = null
private var lastUpdateTime: Instant? = null

fun getFavoritePlaylistWithCache(
    parentId: UUID?,
    callback: (items: List<BaseItemDto>) -> Unit
) {
    if (cachedFavorites != null && lastUpdateTime?.isAfter(Instant.now().minusSeconds(30)) == true) {
        callback(cachedFavorites!!)
        return
    }
    
    // 正常API调用
    getFavoritePlaylist(parentId) { items ->
        cachedFavorites = items
        lastUpdateTime = Instant.now()
        callback(items)
    }
}

分页加载

对于大型音乐库,实现分页加载:

api.itemsApi.getItems(
    startIndex = page * pageSize,
    limit = pageSize,
    // 其他参数...
)

总结

Jellyfin Android TV版音乐专辑收藏功能失效的主要原因是查询条件中缺少对MUSIC_ALBUM类型的支持。通过修改includeItemTypes参数包含BaseItemKind.MUSIC_ALBUM,可以解决这个问题。

建议的修复方案:

  1. 修改ItemListFragmentHelper.kt中的查询条件
  2. 添加适当的测试用例
  3. 考虑性能优化措施

这个修复将确保用户收藏的音乐专辑能够正确显示在收藏列表中,提升整体的音乐体验。


提示:如果您遇到类似问题,可以检查Jellyfin服务器版本是否与客户端兼容,确保两端都支持相同的收藏功能API。

【免费下载链接】jellyfin-androidtv Android TV Client for Jellyfin 【免费下载链接】jellyfin-androidtv 项目地址: https://gitcode.com/gh_mirrors/je/jellyfin-androidtv

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值