Local file reference MP3

Sorry for my English.

Everything works if I pass an external route, an Internet URL. It does not work if I pass a local file.

MainView.ux
<App>

    <Audio ux:Global="Audio" />

    <JavaScript>

        var Audio = require('Audio');

        function play(){
            Audio.Play("1.mp3");
        }

        function stop(){
            Audio.Stop();
        }

        module.exports = {
            play: play,
            stop: stop
        };


    </JavaScript>


    <StackPanel>
        <Switch />
        <Button Text="Play" Clicked="{play}" />
        <Button Text="Stop" Clicked="{stop}" />
    </StackPanel>


</App>

Audio.uno
using Uno;
using Uno.Collections;
using Uno.Compiler.ExportTargetInterop;
using Fuse;
using Fuse.Scripting;
using Uno.IO;

public class Audio : NativeModule
{

    public Audio()
    {        AddMember(new NativeFunction("Play", (NativeCallback)Play));
        AddMember(new NativeFunction("Stop", (NativeCallback)Stop));
    }

    static object Play(Context c, object[] args)
    {
        string url = (string)args[0];
        Play(url);
        return null;
    }

    static object Stop(Context c, object[] args)
    {
        Stop();
        return null;
    }

    [Foreign(Language.Java)]
    static extern(Android) void Play(String url)
    @{
        debug_log("Uno -> Play");
        com.my.Audio mc = new com.my.Audio();
        mc.start(url);
    @}

    [Foreign(Language.Java)]
    static extern(Android) void Stop()
    @{
        debug_log("Uno -> Stop - ");
        com.my.Audio mc = new com.my.Audio();
        mc.stop();
    @}

    static extern(!Android) void Play(String url){ debug_log "fail Play"; }
    static extern(!Android) void Stop(){ debug_log "fail Stop"; }

}

Audio.java
package com.my;

import android.app.Application;

import android.media.MediaPlayer;
import android.media.AudioManager;
import java.io.IOException;


public class Audio
{

  public MediaPlayer player;

  public Audio()
  {     player = new MediaPlayer();
  }

  public void start(String url) {

    try {
      player.setDataSource(url);
    } catch (IOException e) {
      e.printStackTrace();
    } catch (IllegalArgumentException e) {
      e.printStackTrace();
    } catch (SecurityException e) {
      e.printStackTrace();
    } catch (IllegalStateException e) {
      e.printStackTrace();
    }

   try {
      player.prepare();
    } catch (IOException e) {
      e.printStackTrace();
    }

    player.start();

  }

  public void stop() {

    player.reset();
    player.stop();
    player.release();

  }


}

.unoproj
{
  "RootNamespace":"",
  "Packages": [
      "Fuse",
      "FuseJS"
  ],
  "Includes": [
    "*",
    "Audio.java:Java:Android",
    "1.mp3:Bundle",
  ]
}

this helps ?

var filepath = Path.Combine(Directory.GetUserDirectory(UserDirectory.Data), url);

Hi!

You probably need to add the mp3 file as a bundled file. This can be achieved by adding an Includes entry in your .unoproj, like this:

{
    "Includes": [
        "1.mp3:Bundle",

        ...other included files...
    ]
}

You can read more about bundle files over here.

Sebastian Reinhard wrote:

Thank you. But it had already.

Sorry, completely overlooked that :slight_smile:

Unfortunately, I don’t have much experience with android or foreign code, so my ability to help with this is limited. However I found this code snippet, which seems to do what you want. Can you check and see if it works?

The thing with bundled files is that they’re not really files, but rather blocks of embedded data. To access the file for use as a URL in this way you’ll need to unpack the bundled file to a valid path.

Here’s a NativeModule that performs the unpacking task in a pretty blunt way.

https://github.com/Sunjammer/FuseChartExample/blob/master/uno/BundleUnpacker.uno

Thank you so much, now I research.

If you use only java. I created a folder /res/raw/audio.mp3

MediaPlayer.create(this, R.raw.audio);

You could do something like this with fuse?

Yeah but you’d have to do this every time you build your Fuse project then. Build Fuse -> Add res/raw to generated project -> build generated android project. It’s not really viable, at least not right now.