Thursday, September 6, 2012

XBMC with external player [temporary solution for lack of HW acceleration]

You may know the XBMC project ("XBMC is an award-winning free and open source (GPL) software media player and entertainment hub for digital media."), it's awesome, open source and works very well.

But, for now, in android the hardware acceleration is not working.

inRivalz came up with a workaround to use an external player, which has working hardware acceleration, instead of the internal player.

This means using a closed-source alternative, for now.


Basic instructions

Download this apk.

Install it on your device, and modify the playercorefactory.xml (which, according to XBMC Wiki is in Android/data/org.xbmc.xbmc/files/.xbmc/userdata/)

<playercorefactory>
<players>
<player name="MPC-HC" type="ExternalPlayer" audio="false" video="true">
<filename>com.inisoft.mediaplayer.a</filename>
<hidexbmc>true</hidexbmc>
</player>
</players>
<rules action="prepend">
<rule video="true" player="MPC-HC"/>
</rules>
</playercorefactory>

Replace the bold part with either for the corresponding version of the MXPlayer you have installed.
com.mxtech.videoplayer.pro - Pro Edition.
com.mxtech.videoplayer.ad - Free Edition.

Advanced instructions:

Download the source from XBMC Git: Instructions
Apply this patch Link, but replace "StartActivityWithExtra" with this
// External Player
bool CXBMCApp::StartActivityWithExtra(const string &package,const string &path)
{
if (!m_activity || !package.size())
return false;
jthrowable exc;
JNIEnv *env = NULL;
AttachCurrentThread(&env);
jobject oActivity = m_activity->clazz;
jclass cActivity = env->GetObjectClass(oActivity);


// Intent oIntent = new Intent(Intent.ACTION_VIEW);
jclass cIntent = env->FindClass("android/content/Intent");
jmethodID midIntentCtor = env->GetMethodID(cIntent, "<init>", "(Ljava/lang/String;)V");
jstring sIntentView = env->NewStringUTF("android.intent.action.VIEW"); // Intent.ACTION_VIEW
jobject oIntent = env->NewObject(cIntent, midIntentCtor, sIntentView);
env->DeleteLocalRef(sIntentView);
// Uri oUri = Uri.parse(sPath);
jclass cUri = env->FindClass("android/net/Uri");
jmethodID midUriParse = env->GetStaticMethodID(cUri, "parse", "(Ljava/lang/String;)Landroid/net/Uri;");
jstring sPath = env->NewStringUTF(path.c_str());
jobject oUri = env->CallStaticObjectMethod(cUri, midUriParse, sPath);
env->DeleteLocalRef(sPath);
env->DeleteLocalRef(cUri);
// oIntent.setDataAndType(oUri, "video/*");
jmethodID midIntentSetDataAndType = env->GetMethodID(cIntent, "setDataAndType", "(Landroid/net/Uri;Ljava/lang/String;)Landroid/content/Intent;");
jstring sMimeType = NULL;
sMimeType = env->NewStringUTF("video/*");
oIntent = env->CallObjectMethod(oIntent, midIntentSetDataAndType, oUri, sMimeType);
// oIntent.setPackage(sPackage);
jstring sPackage = env->NewStringUTF(package.c_str());
jmethodID mSetPackage = env->GetMethodID(cIntent, "setPackage", "(Ljava/lang/String;)Landroid/content/Intent;");
oIntent = env->CallObjectMethod(oIntent, mSetPackage, sPackage);
env->DeleteLocalRef(sMimeType);
env->DeleteLocalRef(oUri);
env->DeleteLocalRef(cIntent);
env->DeleteLocalRef(sPackage);

// startActivity(oIntent);
jmethodID mStartActivity = env->GetMethodID(cActivity, "startActivity", "(Landroid/content/Intent;)V");
env->CallVoidMethod(oActivity, mStartActivity, oIntent);
env->DeleteLocalRef(cActivity);
env->DeleteLocalRef(oIntent);
exc = env->ExceptionOccurred();
if (exc)
{
CLog::Log(LOGERROR, "CXBMCApp::StartActivity Failed to load %s. Exception follows:", package.c_str());
env->ExceptionDescribe();
env->ExceptionClear();
DetachCurrentThread();
return false;
}
DetachCurrentThread();
return true;
}
// End External Player
The issue with the original code was the method "getLaunchIntentForPackage". This finds the first intent action for the package. The MX Player has both, MAIN and VIEW, but "getLaunchIntentForPackage" only finds the MAIN intent, and for this reason it doesn't work.

Build the source and install it on your device, and modify the playercorefactory.xml (which, according to XBMC Wiki is in Android/data/org.xbmc.xbmc/files/.xbmc/userdata/)

<playercorefactory>
<players>
<player name="MPC-HC" type="ExternalPlayer" audio="false" video="true">
<filename>com.inisoft.mediaplayer.a</filename>
<hidexbmc>true</hidexbmc>
</player>
</players>
<rules action="prepend">
<rule video="true" player="MPC-HC"/>
</rules>
</playercorefactory>

Replace the bold part with either for the corresponding version of the MXPlayer you have installed.

com.mxtech.videoplayer.pro - Pro Edition.
com.mxtech.videoplayer.ad - Free Edition.


No comments:

Post a Comment