[Feature Discuss]修改专辑封面到底应该修改什么?
现在APlayer在这个功能上的实现表现很奇怪。
用例1:
- 打开“忽视MediaStore缓存”。
- 修改某个带有多首歌曲的专辑的封面
预期结果:
- 这张专辑所有的歌曲都应该显示这个新的自定义封面。
实际结果:
- 专辑中只有某首乐曲被修改了封面,且从外层界面看是新的封面,其他仍然保持内嵌。
用例2:
-
在用例1的基础上,关闭“忽视MediaStore缓存”,然后杀死Activity,冷启动APlayer。
-
(如果Merge了我的PR)发现专辑下所有歌曲封面统一为自定义封面。
-
但是,如果再将“忽视MediaStore缓存”打开,结果与用例1相同。
-
那个唯一的被修改了封面的某首乐曲的Tag被永久更改了,而其他同专辑乐曲并未级联更改。
这种实现上的不一致性个人认为是需要解决的。
@cyanlink 忽略媒体缓存,读取的就是歌曲的内嵌封面,完全有可能两首歌是同一专辑,但是用户分别修改了他们的内嵌封面。 而自定义封面如你所说,修改的是整个专辑的封面。
@rRemix 那么依旧存在一个问题,打开“忽略MediaStore缓存”,先修改某个专辑的封面,然后尝试修改这个专辑下没有显示成新封面的单独乐曲的封面,冷重启APlayer之后,这个单独乐曲封面并未生效,还是老的内嵌封面。等于:一个专辑下,只有一首能被设置成自定义封面,而且不受控制,剩下的铁打不动是老内嵌封面,不听用户设置。还是存在行为不一致性。 按照你说的意思我总结一下behavior你看对不对:
- 忽略MS缓存开启 ——>只去优先读取每首歌曲的内嵌封面。
- 用户修改封面——>修改单首歌曲的内嵌封面。//这点目前就是上面说的那个问题。
- 忽略MS缓存关闭——>读取用户设定的“全专辑”封面,应用到每首歌曲。
也就是说,内嵌封面是内嵌封面,是文件自带的;而我们的“软封面”是APlayer自己的cacheDir里存的缓存,那用户修改封面这个功能又去修改了内嵌封面,又影响了“软封面”,而且如上述,这个功能实现还有问题(尚未定位)。
而且在API 30,google已经不让我们直接访问MediaStore的AlbumArt那个Column了,可能读写权限都不给了(没有测试),我猜hack底层content://往albumarts里直接insert values可能都不行了;只能通过一个函数拿到thumbnail。我猜测这么做的用意就是让我们一切听从内嵌?到时候我们该怎么实现呢?
关键问题出在MediaStoreUtil.saveArtwork这里。这个函数的行为解释了我上面列出的所有问题。
@WorkerThread
public static void saveArtwork(Context context, long albumId, File artFile)
throws TagException, ReadOnlyFileException, CannotReadException, InvalidAudioFrameException, IOException, CannotWriteException {
Song song = MediaStoreUtil.getSongByAlbumId(albumId);//这里面只返回了一个象征AlbumID的一个歌曲实例,取songs[0]
if (song == null) {
return;
}
AudioFile audioFile = AudioFileIO.read(new File(song.getUrl()));
Tag tag = audioFile.getTagOrCreateAndSetDefault();
Artwork artwork = ArtworkFactory.createArtworkFromFile(artFile);
tag.deleteArtworkField();
tag.setField(artwork);//这里也就只修改了这一个用户无法控制具体是哪个的、象征这个专辑的歌曲实例的Tag
audioFile.commit();
insertAlbumArt(context, albumId, artFile.getAbsolutePath());//这里又往MediaStore数据库里写“缓存”,其index是每个albumID
}
我估计您当时实现的时候思路混乱了。
关键问题出在MediaStoreUtil.saveArtwork这里。这个函数的行为解释了我上面列出的所有问题。
@WorkerThread public static void saveArtwork(Context context, long albumId, File artFile) throws TagException, ReadOnlyFileException, CannotReadException, InvalidAudioFrameException, IOException, CannotWriteException { Song song = MediaStoreUtil.getSongByAlbumId(albumId);//这里面只返回了一个象征AlbumID的一个歌曲实例,取songs[0] if (song == null) { return; } AudioFile audioFile = AudioFileIO.read(new File(song.getUrl())); Tag tag = audioFile.getTagOrCreateAndSetDefault(); Artwork artwork = ArtworkFactory.createArtworkFromFile(artFile); tag.deleteArtworkField(); tag.setField(artwork);//这里也就只修改了这一个用户无法控制具体是哪个的、象征这个专辑的歌曲实例的Tag audioFile.commit(); insertAlbumArt(context, albumId, artFile.getAbsolutePath());//这里又往MediaStore数据库里写“缓存”,其index是每个albumID }我估计您当时实现的时候思路混乱了。
这个地方确实是,不应该去修改内嵌或者MS,毕竟是自定义的,应该是app自有的封面。我当时好像是听了用户的建议,设置封面的时候就直接修改了内嵌和MS了,这样哪怕app删了或者清除了数据,以前设置的封面还能有效。
关键问题出在MediaStoreUtil.saveArtwork这里。这个函数的行为解释了我上面列出的所有问题。
@WorkerThread public static void saveArtwork(Context context, long albumId, File artFile) throws TagException, ReadOnlyFileException, CannotReadException, InvalidAudioFrameException, IOException, CannotWriteException { Song song = MediaStoreUtil.getSongByAlbumId(albumId);//这里面只返回了一个象征AlbumID的一个歌曲实例,取songs[0] if (song == null) { return; } AudioFile audioFile = AudioFileIO.read(new File(song.getUrl())); Tag tag = audioFile.getTagOrCreateAndSetDefault(); Artwork artwork = ArtworkFactory.createArtworkFromFile(artFile); tag.deleteArtworkField(); tag.setField(artwork);//这里也就只修改了这一个用户无法控制具体是哪个的、象征这个专辑的歌曲实例的Tag audioFile.commit(); insertAlbumArt(context, albumId, artFile.getAbsolutePath());//这里又往MediaStore数据库里写“缓存”,其index是每个albumID }我估计您当时实现的时候思路混乱了。
整个函数都是不需要的,保存了自定义封面就只需要刷新就行了。这个函数应该是用于编辑标签的时候,编辑内嵌封面的。
@rRemix 我找到这个函数就是因为之前弹出Toast里说octet-stream cannot be inserted……,然后通过/audio/albumart那个URI找到的,现在“修改专辑封面”的确会调用这个。换句话说,这函数操作不正交,有副作用hhhh
@rRemix 我找到这个函数就是因为之前弹出Toast里说octet-stream cannot be inserted……,然后通过/audio/albumart那个URI找到的,现在“修改专辑封面”的确会调用这个。换句话说,这函数操作不正交,有副作用hhhh
已经提交了。现在的表现应该正常了。