9

I have to modify the Http Live Streaming implementation of Android Media Player. The implementation is under the stagefright library http://androidxref.com/4.0.4/xref/frameworks/base/media/libstagefright/httplive/LiveDataSource.cpp

I think these library will compile to a libstagefright.so which should be part of the Android system.

My question is if I make some changes to this library and compile a new libstagefright.so. If I load this new libstagefright.so in my new application and call up the media player, will it use the code in my new libstagefright.so?

eroy4u
  • 149
  • 10
  • soulseekah is right that you can't just swap out a system lib. What are you looking to do exactly? – Dave Dec 03 '13 at 09:06
  • I want to modify the HLS implementation to make it read the ID3 metadata from the TS streams. The current android implementation of android media player doesn't provide reading of these metadata. – eroy4u Dec 04 '13 at 02:36
  • You can try submitting a patch to AOSP with the new functionality. – soulseekah Dec 04 '13 at 04:26

2 Answers2

8

You will not be able to replace the original library, since when you try to loadLibrary it will load the library from within /system/lib. So unless you replace that (which is not possible on unrooted devices), you won't be able to load your custom code.

https://github.com/android/platform_system_core/blob/66ed50af6870210ce013a5588a688434a5d48ee9/rootdir/init.environ.rc.in sets the LD_LIBRARY_PATH by default. And loads it from these paths if available. If not, then your application's lib directory will be searched; but not the other way around.

I tried this with libwebkit.so in the past on various mainstream devices and haven't had any luck getting it to load instead of the one in /system/lib.

You can learn more by looking at:

I'm pretty sure you can't replace the default class loader either for security reasons.

What you can do, though, is a straightforward fork the Media Player and have it load your modified libstagefright-modified.so. There could be other solutions, haven't looked at Media Player's code.

soulseekah
  • 7,890
  • 3
  • 47
  • 54
  • Thanks for the answer. Furthermore if I do a straightforward fork and load my modified libstagefright-modified.so, if I create a android.media.MediaPlayer, will it use my libstagefright-modified.so instead of the system libstagefright.so? – eroy4u Dec 04 '13 at 02:39
  • I guess the answeer is No, libstagefright.so is loaded by libmedia_jni.so, which is loaded by android.media.MediaPlayer, so I this way I think I have to recompile lib media_jni.so (change it to depend on libstagefright-modified.so), and recompile android.media.MediaPlayer and possibly some other related libraries in order to use the new functions in libstagefright-modified.so? – eroy4u Dec 04 '13 at 03:58
  • 1
    Yes, you need an independent fork, with all dependent code changed to rely on libstagefright-modified.so. Moreover, you'd need to refactor all the names and packages and look for collisions. See https://stackoverflow.com/questions/10717257/android-ndk-custom-webview-compiling-from-source/11677070#11677070 for a similar idea. – soulseekah Dec 04 '13 at 04:25
4

Knowing that all you want to do is parse the data before it gets to the MediaPlayer, I suggest not trying to alter the Android libraries. As soulseekah mentioned, it's not going to work without a rooted device. There are other options, although they both have drawbacks.

1) If you are only targeting recent versions (4.2 or later, I believe), you can take a look at new classes added to the android.media package, like MediaExtractor and MediaCodec. I'm not greatly familiar with those because they aren't available on the hardware with which I work, but they could be useful in getting to the raw data. Here is a decent sample of using them to play video. The drawback is those classes aren't available in earlier versions.

2) The other option is to put a local proxy on the device. Connect the MediaPlayer to the proxy and make the request to the media server yourself. See my answer here for a little more info on that. With a proxy, you will see all the data that comes through, giving you a chance to parse the ID3 tags. There is the drawback that you will have to parse the TS packets to put together an elementary stream (essentially doing the demuxer's job), but it will work with any version of Android. TS streams aren't difficult to disassemble, and ID3 tags aren't time consuming to parse, so I think this is a reasonable approach.

Community
  • 1
  • 1
Dave
  • 4,208
  • 2
  • 16
  • 24
  • Thanks, for approach 1), using the MediaExtractor, mediaExtractor.setDatasource("http://testing.com/teststream"), I think the app has to download the whole Video files again to read the metadata? so that means downloading the video files two times, this may not be satisfied. – eroy4u Dec 04 '13 at 04:50
  • For approach 2), as HLS is a .m3u8 containing lists of .ts files, so in my local proxy, if it proxy the .m3u8 files and other .ts files it should be good, why it has to parse the TS packets to put together an elementary stream? thanks that's very supportive – eroy4u Dec 04 '13 at 04:53
  • For 1, I don't believe you would need to download twice. You wouldn't use the MediaPlayer at all. Instead it would be your job to pass the byte buffers from the MediaExtractor to an appropriate codec, but you can obviously parse it beforehand. For 2, I simply mean you have to deal with the raw TS streams. The tags you want to parse will be broken into the payloads of the TS packets, meaning you would have to extract those payloads and put together the original media stream before it is meaningful. – Dave Dec 04 '13 at 05:39
  • Thanks for the info. For 1, as you mentioned I'll not be using MediaPlayer at all, so I have to implement my own media player including the HLS implementation- parsing the feed, getting the TS bytes from a correct files, etc. after that I can pass the video to MediaCodec to play the video. Is it the right approach? looks like there's much work to reimplement the HLS – eroy4u Dec 04 '13 at 05:50
  • As I said, I'm not too familiar with those classes. I believe the MediaExtractor does the de-multiplexing for you (including extracting the payloads of the TS packets), which means the rest shouldn't be terribly difficult. If that really is the case, you would need to download the m3u8 and use a MediaExtractory/MediaCodec algorithm like in the example link for each successive TS stream. I think you would have a chance to parse the ID3 tags after the call to `readSampleData`. – Dave Dec 04 '13 at 06:49
  • I have used the second option and successfully extracted ID3 tags – anz Dec 09 '13 at 11:15
  • Cool, you have the same scenario as I do? is it HLS? would you mind if you tell me what library you're using for the local proxy? – eroy4u Dec 10 '13 at 03:27