1
votes

I'm trying to set the data source for a media player, but it keeps throwing this exception.

java.io.IOException: setDataSourceFD failed

Where am I going wrong?

java.io.IOException: setDataSourceFD failed.: status=0x80000000
    at android.media.MediaPlayer._setDataSource(Native Method)
    at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1025)
02-05 11:11:37.664 I/mono-stdout(19741):   at Android.Runtime.JNIEnv.CallVoidMethod (IntPtr jobject, IntPtr jmethod, Android.Runtime.JValue[] parms) [0x00063] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.10.2-branch/4b53fbd0/source/monodroid/src/Mono.Android/src/Runtime/JNIEnv.g.cs:507 
    at futurestate.audiobook.droid.ui.views.home.HomeView.n_onCreate(Native Method)
    at futurestate.audiobook.droid.ui.views.home.HomeView.onCreate(HomeView.java:31)
    at android.app.Activity.performCreate(Activity.java:5231)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
    at android.app.ActivityThread.access$800(ActivityThread.java:135)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:136)
    at android.app.ActivityThread.main(ActivityThread.java:5017)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
    at

Here's my code. The Player.SetDataSource() is the failing line.

if (Player == null)
{
    try
    {
        var expansionFile = ApkExpansionSupport.GetApkExpansionZipFile(Application.Context, 1, 0);
        var entry = expansionFile.GetEntry(FileName);

        // I can see all entries with the line below. 
        // Therefore the above code can reach into the obb and see the contents.
        // var entries = expansionFile.GetAllEntries();

        var pfd = ParcelFileDescriptor.Open(new File(entry.ZipFileName), ParcelFileMode.ReadOnly);
        var afd = new AssetFileDescriptor(pfd, entry.FileOffset, entry.FileSize);
        var fd = afd.FileDescriptor;

        Player = new MediaPlayer();
        Player.Reset();
        Player.SetWakeMode(Application.Context, WakeLockFlags.Partial);
        Player.Looping = false;

        Player.SetDataSource(fd, afd.StartOffset, afd.Length);
        Player.Prepare();
    }
    catch (Exception ex)
    {
        Console.Out.WriteLine(ex.Message);
        Console.Out.WriteLine(ex.Source);
        Console.Out.WriteLine(ex.InnerException);
        Console.Out.WriteLine(ex.StackTrace);
    }

    SeekTo(_startingPointMsec);
    DurationMsec = (Player.Duration);
}
1

1 Answers

0
votes

Well, I suppose I don't know if I should feel stupid or plain mad. The whole problem with my approach was due to the fact that Microsoft's idea of "NoCompression" is a little askew.

note: the code in the question works and is correct"

The problem comes out of the fact that I was using Powershell to automate the creation of my .obb file. The script was leveraging System.IO.Compression, and when I set the System.IO.Compression.CompressionLevel to NoCompression, it still mangled my obb file.

I fired up my console and installed 7zip (ps: rocks.)

> cinst 7zip

and recreated the obb file using the Store mode, and everything worked.

enter image description here

Now that this is figured out, here's our PowerShell build script

function Invoke-CreateExpansionApk
{
    param(
        [Parameter(Position=0, HelpMessage="Type of apk to create: main|patch")]
        [ValidateSet('main','patch')]
        [System.String]$Type = 'main',
        [Parameter(Position=1, Mandatory=$true, HelpMessage="Must be the same name as your Play Store App")]
        [System.String]$ApkName,

        [Parameter(Position=2, Mandatory=$true)]
        [System.String]$SourceDir,
        [Parameter(Position=3, Mandatory=$true)]
        [System.String]$OutputDir,
        [Parameter(Position=4)]
        [System.Double]$Version = 1
    )
    $PRIVATE:bundleVersion = $Version

    $PRIVATE:fileName = "$OutputDir\$Type.$bundleVersion.$ApkName.obb"

    $pwd = Get-ModuleDirectory
    set-alias sz $pwd\7za.exe
    sz a -tzip $fileName $SourceDir -mx0
}