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);
}
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: chocolatey rocks.)
> cinst 7zip
and recreated the obb file using the Store
mode, and everything worked.
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
}