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

Android@10 not playing files served via https://localhost #345

Open
3 tasks done
boedy opened this issue Jun 1, 2022 · 6 comments
Open
3 tasks done

Android@10 not playing files served via https://localhost #345

boedy opened this issue Jun 1, 2022 · 6 comments

Comments

@boedy
Copy link

boedy commented Jun 1, 2022

Bug Report

Problem

Files stored on the device which are accessed through https://localhost should start playing, but don't. Files play fine if accessed directly from the web. A simple Html5 player is able to play the file normally through localhost.

Information

LogCat logs when playing file:

2022-06-01 20:59:30.446 23784-23895/io.cordova.hellocordova V/MediaHTTPService: MediaHTTPService(android.media.MediaHTTPService@771fbf7): Cookies: null
2022-06-01 20:59:30.456 23784-23895/io.cordova.hellocordova W/MediaPlayer: Use of stream types is deprecated for operations other than volume control
2022-06-01 20:59:30.456 23784-23895/io.cordova.hellocordova W/MediaPlayer: See the documentation of setAudioStreamType() for what to use instead with android.media.AudioAttributes to qualify your playback use case
2022-06-01 20:59:30.459 23784-23895/io.cordova.hellocordova W/AudioManager: Use of stream types is deprecated for operations other than volume control
2022-06-01 20:59:30.459 23784-23895/io.cordova.hellocordova W/AudioManager: See the documentation of requestAudioFocus() for what to use instead with android.media.AudioAttributes to qualify your playback use case
2022-06-01 20:59:30.462 23784-23895/io.cordova.hellocordova W/PluginManager: THREAD WARNING: exec() call to Media.startPlayingAudio blocked the main thread for 25ms. Plugin should use CordovaInterface.getThreadPool().
2022-06-01 20:59:30.463 23784-23884/io.cordova.hellocordova V/MediaHTTPService: makeHTTPConnection: CookieManager created: java.net.CookieManager@73fb182
2022-06-01 20:59:30.464 23784-23884/io.cordova.hellocordova V/MediaHTTPService: makeHTTPConnection(android.media.MediaHTTPService@771fbf7): cookieHandler: java.net.CookieManager@73fb182 Cookies: null
2022-06-01 20:59:30.468 23784-23784/io.cordova.hellocordova I/chromium: [INFO:CONSOLE(245)] "1", source: https://localhost/plugins/cordova-plugin-media/www/Media.js (245)
2022-06-01 20:59:30.724 23784-23846/io.cordova.hellocordova D/: PlayerBase::stop() from IPlayer
2022-06-01 20:59:30.724 23784-23846/io.cordova.hellocordova D/AudioTrack: stop() called with 980792 frames delivered
2022-06-01 21:00:00.719 23784-23884/io.cordova.hellocordova E/MediaPlayerNative: error (1, -2147483648)
2022-06-01 21:00:00.720 23784-23895/io.cordova.hellocordova E/MediaPlayer: Error (1,-2147483648)
2022-06-01 21:00:00.720 23784-23895/io.cordova.hellocordova D/AudioPlayer: AudioPlayer.onError(1, -2147483648)
2022-06-01 21:00:00.721 23784-23895/io.cordova.hellocordova V/MediaPlayer: resetDrmState:  mDrmInfo=null mDrmProvisioningThread=null mPrepareDrmInProgress=false mActiveDrmScheme=false
2022-06-01 21:00:00.721 23784-23895/io.cordova.hellocordova V/MediaPlayer: cleanDrmObj: mDrmObj=null mDrmSessionId=null
2022-06-01 21:00:00.729 23784-23784/io.cordova.hellocordova I/chromium: [INFO:CONSOLE(261)] "[object Object]", source: https://localhost/plugins/cordova-plugin-media/www/Media.js (261)

Notice the error:

2022-06-01 21:00:00.719 23784-23884/io.cordova.hellocordova E/MediaPlayerNative: error (1, -2147483648)
2022-06-01 21:00:00.720 23784-23895/io.cordova.hellocordova E/MediaPlayer: Error (1,-2147483648)

Command or Code

Some code snippets that can be run in chrome console when inspecting device

Download sample wav file

(() => {
  const fileTransfer = new FileTransfer();
  const TIMEOUT_INTERVAL = 30 * 1000;
  const filePath = window.cordova.file.dataDirectory + "test.wav";
  
  fileTransfer.download(
    "https://github.com/prof3ssorSt3v3/media-sample-files/blob/master/jimmy-coffee.wav?raw=true",
    filePath,
    file => console.log(file.toURL()),
    error => console.error(error)
  );
})()
// returns: https://localhost/__cdvfile_files__/test.wav

NOT WORKING: Play file locally with cordova-plugin-media (This is the bug)

source = 'http://localhost/__cdvfile_files__/test.wav';
track = new Media(source, null, console.error, console.log);
track.play();

WORKING: Play file remotely with cordova-plugin-media

source = 'https://github.com/prof3ssorSt3v3/media-sample-files/blob/master/jimmy-coffee.wav?raw=true';
track = new Media(source, null, console.error, console.log);
track.play();

WORKING: Play file locally with html5

sound = new Audio("http://localhost/__cdvfile_files__/test.wav");
sound.play();

Environment, Platform, Device

Device: Android 8.1 (API 27)

Version information

Cordova CLI: 11.0.0
Cordova Platforms: android 10.1.2
Cordova Plugins:

  • cordova-plugin-file-transfer 2.0.0-dev "File Transfer"
  • cordova-plugin-file 7.0.0 "File"
  • cordova-plugin-media 6.0.0 "Media"

Checklist

  • I searched for existing GitHub issues
  • I updated all Cordova tooling to most recent version
  • I included all the necessary information above
@boedy
Copy link
Author

boedy commented Jun 2, 2022

I believe this plugin can't access files through the https://localhost scope. I believe that the WebViewAssetLoader (apache/cordova-android#1137) that was implemented in Android@10 can only be reached though the WebView. All requests that happen outside of the WebView will not be resolved.

@ghenry22
Copy link
Contributor

ghenry22 commented Jun 6, 2022

That HTTPS url is only available inside your webview. When you use the media plugin it works outside of the webview. Provide the file path directly to the media plugin and it will play fine.

If you want to use HTML5 audio then you should use the HTTPS://localhost... address as this exposes the locally stored files to the webview so they can be accessed in HTML.

@boedy
Copy link
Author

boedy commented Jun 6, 2022

Yes, that's the case. I would argue that the media plugin should interoperate 'https://localhost' (port 80 only) urls and resolve its native file path internally. Removes the need for app developers to implement this mapping logic themselves.

Better yet. A helper function provided by cordova plugin class as suggested here apache/cordova-android#1316 (comment) would abstract it for plugin developers too.

@breautek
Copy link

breautek commented Jun 6, 2022

Yes, that's the case. I would argue that the media plugin should interoperate 'https://localhost' (port 80 only) urls and resolve its native file path internally. Removes the need for app developers to implement this mapping logic themselves.

Better yet. A helper function provided by cordova plugin class as suggested here apache/cordova-android#1316 (comment) would abstract it for plugin developers too.

We are experimenting with a solution similar to this, available in the file plugin 7.x

apache/cordova-plugin-file#517

Does this solves your issue?

@boedy
Copy link
Author

boedy commented Jun 6, 2022

I don't think so. That PR seems to fix an issue with the asset folder not being reachable through the WebViewAssetLoader.

My second remark is referring to your comment:

Native could probably parse the url and transform it to a regular file:// url. I think the cordova plugin class could also provide this url transform implementation.

@SteveGilvarry
Copy link

SteveGilvarry commented Aug 21, 2022

@breautek first apologies I don't have much background with Cordova, but attempting to support an app. In reference to this comment

We are experimenting with a solution similar to this, available in the file plugin 7.x

apache/cordova-plugin-file#517

Does this solves your issue?

Are you suggesting that https://github.com/apache/cordova-plugin-file/blob/ef301bcd17bd2e86367cdf90b7f1b06a84f71f1b/src/android/FileUtils.java#L1267 could be used by other plugins to convert the https://localhost/__cdvfiles_XXXX links back into plugin java side useable links?

Or that other plugins also implement the same code to perform the same conversion? I was trying to understand exactly what CordovaPluginPathHandler getPathHandler() is, some form of per plugin override? I don't see it called from anywhere in the File plugin, and looks like nothing was documented for it.

My use case is another plugin, but same issue where entry.toURL is returning the web view only URL and I am then passing that into another plugin to access the file. If I can work out how to do it for the plugin I have I will happily attempt a PR for this one.

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

No branches or pull requests

4 participants