Skip to content
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

Downloading/manipulating M4B file adds a .MP3 file extension #94

Open
advplyr opened this issue Jul 20, 2022 · 8 comments
Open

Downloading/manipulating M4B file adds a .MP3 file extension #94

advplyr opened this issue Jul 20, 2022 · 8 comments
Labels
enhancement New feature or request

Comments

@advplyr
Copy link

advplyr commented Jul 20, 2022

Library version: 1.0.0+
OS version: Android 11 & 12
Device model: OnePlus6 & Pixel 6

Describe the bug
In debugging this issue advplyr/audiobookshelf-app#292 I found that starting at release v1.0.0 downloading .M4B audiobooks will add a .MP3 extension at the end.

I am able to resolve this issue by using v0.14.0

To Reproduce
Download or move a .m4b file on v1.0.0 or above

@anggrayudi
Copy link
Owner

anggrayudi commented Jul 21, 2022

What's the mime type you're using when saving the M4B files? Are you using audio/mp4a-latm or audio/mpeg?
Listed on this website:

  • audio/mp4a-latm for M4B
  • audio/mpeg for MP3

@advplyr
Copy link
Author

advplyr commented Jul 24, 2022

The server was using node-express sendFile to serve the files which was setting the mime type based on the file extension.

I found out that M4B was not listed in the mime type db they use (https://github.com/jshttp/mime-db/blob/master/db.json)
so the mime type was application/octet-stream, which explains some other issues we've had.

I updated the server to use our internal set of mime types that uses audio/mp4 for M4B

I'm not positive but I think audio/mp4 is the best mime type for M4A and M4B files

Both M4A and M4B format are basically an audio file extension of MP4 codec, and encoded by AAC (Advanced Audio Coding)

https://www.tunefab.com/tutorials/m4a-vs-m4b.html

Will SimpleStorage handle M4B correctly with audio/mp4?

@anggrayudi
Copy link
Owner

anggrayudi commented Jul 24, 2022

SimpleStorage relies on OS level android.webkit.MimeTypeMap to retrieve the file extension, which is statically hardcoded by the system. For example, the following code will return *.bin on OS 10+, but no extension on older OS level:

val fileExtension = MimeTypeMap.getSingleton().getExtensionFromMimeType("application/octet-stream")

I will make a feature that can handle file extensions globally, regardless of the API levels by using the mime type DB you suggested. Thanks for the idea! I'll let this issue open until the feature is merged.

BTW, you had better to use SimpleStorage v1.4.1, because it contains many bugfixes. Since current Android OS does not handle M4B yet, then just use mime type */* explicitly to create M4B with v1.4.1. SimpleStorage v0.14.0 uses */* implicitly, that's why it worked.

@anggrayudi anggrayudi added the enhancement New feature or request label Jul 24, 2022
@advplyr
Copy link
Author

advplyr commented Jul 24, 2022

Is there a way I can set this from the android app without having to serve the file with mime type */*?

The server is serving files to many different clients and not just the android app so I would like to keep the mime type audio/mp4 coming from the server.

The mime type DB I shared is just what node-express uses, but it is missing the mime type for the file extension I actually need so if you do use it I hope you would add M4B in there.

Update: I'm not sure I understand correctly. If the server uses audio/mp4 for M4B or M4A files will this cause a problem?

@anggrayudi
Copy link
Owner

Is there a way I can set this from the android app without having to serve the file with mime type /?

No. It is the limitation from the OS itself. Nothing we can do. Using */* is the only way. To check if you can use mime type audio/mp4, simply:

val fileExtension = MimeTypeMap.getSingleton().getExtensionFromMimeType("audio/mp4") ?: "*/*"

I hope you would add M4B in there.

Sure. I just need to find more reliable online mime type database out there. Please tell me if you know something better.

If the server uses audio/mp4 for M4B or M4A files will this cause a problem?

Use */* if the received mime type from the server is not recognized by android.webkit.MimeTypeMap, for example:

val mimeTypeFromServer = ...
val fileExtension = MimeTypeMap.getSingleton().getExtensionFromMimeType(mimeTypeFromServer) ?: "*/*"

@advplyr
Copy link
Author

advplyr commented Jul 24, 2022

Use / if the received mime type from the server is not recognized by android.webkit.MimeTypeMap

I'm not sure what you mean by this. How do I use a different mime type after the file has been downloaded?

I don't think this explains why .mp3 was being appended to the M4B file with mime type application/octet-stream.

SimpleStorage was appending a file extension even though the file already had a file extension. That is the reason I'm asking if I use audio/mp4 as the mime type for a file with extension .m4b is SimpleStorage going to append .mp4?

@anggrayudi
Copy link
Owner

anggrayudi commented Jul 28, 2022

How do I use a different mime type after the file has been downloaded?

I think I know what you mean. It is caused by extension function moveFileTo(). I have to check & reproduce it.

What is the previous file location before you moving the files? Maybe in /storage/emulated/0/Android/data/<packageName>/files?

@advplyr
Copy link
Author

advplyr commented Jul 28, 2022

The user selects a folder on their device where they want the audio files to go.

Downloading directly to their selected folder was crashing on certain devices (something with permissions) so I set it up to first download everything to the downloads folder:

val tempFolderPath = mainActivity.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)

then after all the audio files are downloaded they are moved into the folder the user selected.
This resolved the issue with downloading files directly into their folder but might not be necessary if I figure out what the underlying issue was.

So to answer your question the files are downloaded to DIRECTORY_DOWNLOADS

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants