B4A Library Exoplayer 2.18.5 Streams Player

Hi, This is Based on the Wrapper of Erel .
I was in need to use the latest Exoplayer for only one purpose is to play RTMP Streams.
also this Exoplayer Replaces deprecated playerview with StyledPlayerView.

You need this Additional Following AArs to be located in your Additional Libraries Folder in order to use this library.

Version 1.40 required aar.

Additional AAR 2.18.2

Version 1.50 required aar.
Additional AAR 2.18.3

Version 1.60 required aar.
Additional AAR 2.18.4

Version 1.70 required aar.
Additional AAR 2.18.5

Functionality :
  • CreateUriSource
  • CreateSmoothStreamingSource
  • CreateHLSSource
  • CreateDashSource
  • CreateFileSource
  • CreateRtspStreamingSource
  • CreateRtmpStreamingSource
  • CreateUdpStreamingSource
  • CreateListSource
  • setReapeatMode
  • getIsPlaying
  • Prepare
  • Play
  • Pause
  • Release
  • getPosition
  • setPosition
  • getDuration
  • getVolume
  • setVolume
  • getCurrentMediaItemIndex
  • GetvideoFormatwidth
  • GetvideoFormatHeight
  • GetAudioTracksLanguages
  • GetVideoTrackSubtitles
  • preferedAudioLanguage
  • preferedtextLanguage
  • EnableSubtitles


DesignerProperties

  • SPlayerView
  • ResizeMode [FIT|FIXED_HEIGHT|FIXED_WIDTH]
  • UseController default is true
  • ShowBuffering [NEVER|PLAYING|ALWAYS] default is NEVER
  • ControllerTimeout default is 5000
I may Extends More functionality in the future .

Requires Appcompat Library

Example is included.

Events :

  • Player_Ready
  • Player_Error
  • Player_Complete
  • IDLE
  • Buffering
Update Version 1.40
  • FFMPEG Extension is Supported
  • FFmpegavailabe << to check weather ffmpeg is available or not.
  • FFMPEG Initialize Choice during initialization Prefer To use FFMPEGAUDIO Decoding only for now
  • player.Initialize("player", UseFFmpeg as boolean, FFMPEGAUDIO As boolean, FFmpegVideo As Boolean)
  • FFMPEG AUDIO AND VIDEO Decoder
Updated Version 1.50
Upgrade to latest exoplayer 2.18.3

Change Log

Updated Version 1.60
  • Upgraded to the latest ExoPlayer 2.18.4 > Change Log
  • Fixed GetvideoFormatwidth, GetvideoFormatHeight when playing media without video it will return -1 if the media doesn't have video.
  • Added Stop method to stop the player.
Updated Version 1.70
  • Upgraded to the latest ExoPlayer 2.18.5
  • Added IDLE EVENT and Buffering Event.
download additional aar to use the latest exoplayer fixes.
 

Attachments

  • addoexo-1.40.zip
    22 KB · Views: 284
  • addoexo-1.50.zip
    22 KB · Views: 184
  • addoexo-1.60.zip
    22 KB · Views: 210
  • addoexo-1.70.zip
    22.1 KB · Views: 409
Last edited:

Addo

Well-Known Member
Licensed User
As noticed and reported in some cases there was incompatibility between Exoplayer Main source that been published by google and the FFmpeg VideoDecoder
this will take a huge work to customize the Exoplayer Source which is already not recommended.
this new update will make you choose what do you want to do with the ffmpeg decoder, weather you want to use audio decoding or video decoding,
Using FFmpeg in general should be set if you want to use ffmpeg as the main decoder.
You can use FFmpeg to decode Audio and let the hardware decode the video and vise versa.
it is mandatory to redownload the additional aar.

Update Version 1.40

  • FFMPEG Initialize Choice during initialization Prefer To use FFMPEGAUDIO Decoding only for now
  • player.Initialize("player", UseFFmpeg as boolean, FFMPEGAUDIO As boolean, FFmpegVideo As Boolean)
  • FFMPEG AUDIO AND VIDEO Decoder
library updated in the first Post.
 

Zero7

Member
Hello,

I think there's a bug with .GetvideoFormatHeight / .GetvideoFormatWidth.

If the SPlayer is playing a audio file (mp3 in this case) I get a crash in player_ready() event if I try to read the values of .GetvideoFormatHeight / .GetvideoFormatWidth:

B4X:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Class java.lang.Object.getClass()' on a null object reference

It should return 0 or -1 both because is playing a audio file (no video).

Currently I'm using the videoformatwidth to known if as file with video or without:

B4X:
 myplayer.IsVideo = (splayer.GetVideoFormatWidth > 0)

Another thing I miss is a .stop action (there's a play and pause but not stop).
 

Addo

Well-Known Member
Licensed User
Another thing I miss is a .stop action (there's a play and pause but not stop).
Will add this in the next update.
If the SPlayer is playing a audio file (mp3 in this case) I get a crash in player_ready() event if I try to read the values of .GetvideoFormatHeight / .GetvideoFormatWidth:

B4X:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Class java.lang.Object.getClass()' on a null object reference

It should return 0 or -1 both because is playing a audio file (no video).
Will be fixed also in the next update.
 

nedium

Active Member
Licensed User
Longtime User
Updated Version 1.60
  • Upgraded to the latest ExoPlayer 2.18.4 > Change Log
  • Fixed GetvideoFormatwidth, GetvideoFormatHeight when playing media without video it will return -1 if the media doesn't have video.
  • Added Stop method to stop the player.
download additional aar to use the latest exoplayer fixes.
Thank you,
 

Zero7

Member
Hello @Addo,

I got a problem. Seems that Exoplayer crash when try to play this stream, for eg:

B4X:
https://ztnr.rtve.es/ztnr/1688877.m3u8

B4X:
13/03/23 14:12:51: [UI_InitPlayer] Init OK!
13/03/23 14:12:51: [UI_InitPlayer] FFMPEG: true, FFMPEG_AUD: true, FFMPEG_VID: true

The crash:

B4X:
Fatal signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0x720754e000 in tid 25569 (ExoPlayer:Playb), pid 25295 (cbn.pl_srv)
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'Xiaomi/raphael/raphael:11/RKQ1.200826.002/21.11.24:user/release-keys'
Revision: '0'
ABI: 'arm64'
Timestamp: 2023-03-13 14:13:07+0100
pid: 25295, tid: 25569, name: ExoPlayer:Playb  >>> cbn.pl_srv <<<
uid: 10328
signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0x720754e000
    x0  000000720754de00  x1  0000000075a16010  x2  00000000000001b0  x3  000000720754dfc0
    x4  0000000075a16210  x5  000000720754e200  x6  7a7a7a7a7a7a7a7a  x7  7a7a7a7a7a7a7a7a
    x8  7a7a7a7a7a7a7a7a  x9  7a7a7a7a7979797a  x10 7979797a7b7a797a  x11 7979797979797979
    x12 7c7c7c7c7c7c7c7c  x13 7a7a7a7a7a7a7a7b  x14 0000000000000030  x15 0000000000000001
    x16 00000071a15f12a8  x17 000000729d493c40  x18 000000719f26e000  x19 000000720a6b4cf0
    x20 0000000000000200  x21 0000000000000400  x22 000000720754de00  x23 0000000075a15e10
    x24 0000000000000000  x25 0000000000000000  x26 0000000075a3a010  x27 0000000000000200
    x28 0000000000090000  x29 00000071a0073db0
    lr  00000071a123c5c4  sp  00000071a0073d50  pc  000000729d493bf8  pst 0000000020000000
backtrace:
      #00 pc 0000000000088bf8  /apex/com.android.runtime/lib64/bionic/libc.so (__memcpy+296) (BuildId: d2bad1502ac7810a2cce958ef2191244)
      #01 pc 00000000000b85c0  /data/app/~~d9P-afrEGRH5NQuVt8udAQ==/cbn.pl_srv-uJ42vp45jrgsu0b3hoFBtw==/lib/arm64/libffmpegJNI.so (Java_com_google_android_exoplayer2_ext_ffmpeg_FfmpegVideoDecoder_ffmpegRenderFrame+736) (BuildId: 5c3bb0e395d619abbb0a312094881fbf5d0cd75f)
      #02 pc 00000000000276fc  /data/app/~~d9P-afrEGRH5NQuVt8udAQ==/cbn.pl_srv-uJ42vp45jrgsu0b3hoFBtw==/oat/arm64/base.odex (art_jni_trampoline+204)
      #03 pc 0000000000133564  /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+548) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #04 pc 0000000000197e94  /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+204) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #05 pc 0000000000305328  /apex/com.android.art/lib64/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+376) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #06 pc 00000000003014b0  /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall<true, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+696) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #07 pc 000000000063918c  /apex/com.android.art/lib64/libart.so (MterpInvokeDirectRange+456) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #08 pc 000000000012dc14  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_direct_range+20) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #09 pc 0000000000397a10  /data/app/~~d9P-afrEGRH5NQuVt8udAQ==/cbn.pl_srv-uJ42vp45jrgsu0b3hoFBtw==/oat/arm64/base.vdex (com.google.android.exoplayer2.ext.ffmpeg.FfmpegVideoDecoder.renderToSurface+28)
      #10 pc 000000000063a368  /apex/com.android.art/lib64/libart.so (MterpInvokeVirtualQuick+1268) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #11 pc 0000000000131594  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_virtual_quick+20) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #12 pc 0000000000397c00  /data/app/~~d9P-afrEGRH5NQuVt8udAQ==/cbn.pl_srv-uJ42vp45jrgsu0b3hoFBtw==/oat/arm64/base.vdex (com.google.android.exoplayer2.ext.ffmpeg.FfmpegVideoRenderer.renderOutputBufferToSurface+8)
      #13 pc 000000000063a368  /apex/com.android.art/lib64/libart.so (MterpInvokeVirtualQuick+1268) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #14 pc 0000000000131594  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_virtual_quick+20) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #15 pc 0000000000467aa6  /data/app/~~d9P-afrEGRH5NQuVt8udAQ==/cbn.pl_srv-uJ42vp45jrgsu0b3hoFBtw==/oat/arm64/base.vdex (com.google.android.exoplayer2.video.DecoderVideoRenderer.renderOutputBuffer+150)
      #16 pc 000000000063a368  /apex/com.android.art/lib64/libart.so (MterpInvokeVirtualQuick+1268) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #17 pc 0000000000131594  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_virtual_quick+20) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #18 pc 00000000004671e2  /data/app/~~d9P-afrEGRH5NQuVt8udAQ==/cbn.pl_srv-uJ42vp45jrgsu0b3hoFBtw==/oat/arm64/base.vdex (com.google.android.exoplayer2.video.DecoderVideoRenderer.processOutputBuffer+322)
      #19 pc 0000000000636060  /apex/com.android.art/lib64/libart.so (MterpInvokeDirect+1164) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #20 pc 000000000012d914  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_direct+20) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #21 pc 0000000000466dcc  /data/app/~~d9P-afrEGRH5NQuVt8udAQ==/cbn.pl_srv-uJ42vp45jrgsu0b3hoFBtw==/oat/arm64/base.vdex (com.google.android.exoplayer2.video.DecoderVideoRenderer.drainOutputBuffer+140)
      #22 pc 0000000000636060  /apex/com.android.art/lib64/libart.so (MterpInvokeDirect+1164) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #23 pc 000000000012d914  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_direct+20) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #24 pc 0000000000467994  /data/app/~~d9P-afrEGRH5NQuVt8udAQ==/cbn.pl_srv-uJ42vp45jrgsu0b3hoFBtw==/oat/arm64/base.vdex (com.google.android.exoplayer2.video.DecoderVideoRenderer.render+124)
      #25 pc 00000000006354cc  /apex/com.android.art/lib64/libart.so (MterpInvokeInterface+1840) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #26 pc 000000000012da14  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_interface+20) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #27 pc 000000000035a4fa  /data/app/~~d9P-afrEGRH5NQuVt8udAQ==/cbn.pl_srv-uJ42vp45jrgsu0b3hoFBtw==/oat/arm64/base.vdex (com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork+202)
      #28 pc 0000000000636060  /apex/com.android.art/lib64/libart.so (MterpInvokeDirect+1164) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #29 pc 000000000012d914  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_direct+20) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #30 pc 0000000000358b8c  /data/app/~~d9P-afrEGRH5NQuVt8udAQ==/cbn.pl_srv-uJ42vp45jrgsu0b3hoFBtw==/oat/arm64/base.vdex (com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage+440)
      #31 pc 00000000006354cc  /apex/com.android.art/lib64/libart.so (MterpInvokeInterface+1840) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #32 pc 000000000012da14  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_interface+20) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #33 pc 0000000000623c4c  [anon:dalvik-classes2.dex extracted in memory from /system/framework/framework.jar!classes2.dex] (android.os.Handler.dispatchMessage+24)
      #34 pc 0000000000633b38  /apex/com.android.art/lib64/libart.so (MterpInvokeVirtual+1440) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #35 pc 000000000012d814  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_virtual+20) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #36 pc 000000000064d592  [anon:dalvik-classes2.dex extracted in memory from /system/framework/framework.jar!classes2.dex] (android.os.Looper.loop+498)
      #37 pc 00000000006368c0  /apex/com.android.art/lib64/libart.so (MterpInvokeStatic+1120) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #38 pc 000000000012d994  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_static+20) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #39 pc 000000000062470c  [anon:dalvik-classes2.dex extracted in memory from /system/framework/framework.jar!classes2.dex] (android.os.HandlerThread.run+56)
      #40 pc 00000000002f7e1c  /apex/com.android.art/lib64/libart.so (art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.8987581780827286127)+268) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #41 pc 0000000000622510  /apex/com.android.art/lib64/libart.so (artQuickToInterpreterBridge+796) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #42 pc 000000000013cff8  /apex/com.android.art/lib64/libart.so (art_quick_to_interpreter_bridge+88) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #43 pc 0000000000133564  /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+548) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #44 pc 0000000000197e94  /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+204) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #45 pc 000000000052aefc  /apex/com.android.art/lib64/libart.so (art::(anonymous namespace)::InvokeWithArgArray(art::ScopedObjectAccessAlreadyRunnable const&, art::ArtMethod*, art::(anonymous namespace)::ArgArray*, art::JValue*, char const*)+104) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #46 pc 000000000052c0fc  /apex/com.android.art/lib64/libart.so (art::JValue art::InvokeVirtualOrInterfaceWithJValues<art::ArtMethod*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, art::ArtMethod*, jvalue const*)+440) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #47 pc 0000000000579474  /apex/com.android.art/lib64/libart.so (art::Thread::CreateCallback(void*)+1272) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #48 pc 00000000000f4204  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+64) (BuildId: d2bad1502ac7810a2cce958ef2191244)
      #49 pc 000000000008ec64  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: d2bad1502ac7810a2cce958ef2191244)
** Receiver (svc) OnReceive **
*** Service (svc) Create ***

The same code I using works well on Android Emulator (x86) but don't work in my phone (Redmi K20 Pro) and the car Android Unit (Android 8).

Edit:

If use this code: Engine.Initialize("player", True, True, False) it works, but Engine.Initialize("player", True, True, True) it does crash, so seems a problem with the FFMPEG Video decoder. Maybe some library is missing? or wrong arquitecture? because it works in a x86 emulator.
 
Last edited:

Addo

Well-Known Member
Licensed User
As noticed and reported in some cases there was incompatibility between Exoplayer Main source that been published by google and the FFmpeg VideoDecoder
this will take a huge work to customize the Exoplayer Source which is already not recommended.
this new update will make you choose what do you want to do with the ffmpeg decoder, weather you want to use audio decoding or video decoding,
Using FFmpeg in general should be set if you want to use ffmpeg as the main decoder.
You can use FFmpeg to decode Audio and let the hardware decode the video and vise versa.
Hello @Addo,

I got a problem. Seems that Exoplayer crash when try to play this stream, for eg:

B4X:
https://ztnr.rtve.es/ztnr/1688877.m3u8

B4X:
13/03/23 14:12:51: [UI_InitPlayer] Init OK!
13/03/23 14:12:51: [UI_InitPlayer] FFMPEG: true, FFMPEG_AUD: true, FFMPEG_VID: true

The crash:

B4X:
Fatal signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0x720754e000 in tid 25569 (ExoPlayer:Playb), pid 25295 (cbn.pl_srv)
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'Xiaomi/raphael/raphael:11/RKQ1.200826.002/21.11.24:user/release-keys'
Revision: '0'
ABI: 'arm64'
Timestamp: 2023-03-13 14:13:07+0100
pid: 25295, tid: 25569, name: ExoPlayer:Playb  >>> cbn.pl_srv <<<
uid: 10328
signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0x720754e000
    x0  000000720754de00  x1  0000000075a16010  x2  00000000000001b0  x3  000000720754dfc0
    x4  0000000075a16210  x5  000000720754e200  x6  7a7a7a7a7a7a7a7a  x7  7a7a7a7a7a7a7a7a
    x8  7a7a7a7a7a7a7a7a  x9  7a7a7a7a7979797a  x10 7979797a7b7a797a  x11 7979797979797979
    x12 7c7c7c7c7c7c7c7c  x13 7a7a7a7a7a7a7a7b  x14 0000000000000030  x15 0000000000000001
    x16 00000071a15f12a8  x17 000000729d493c40  x18 000000719f26e000  x19 000000720a6b4cf0
    x20 0000000000000200  x21 0000000000000400  x22 000000720754de00  x23 0000000075a15e10
    x24 0000000000000000  x25 0000000000000000  x26 0000000075a3a010  x27 0000000000000200
    x28 0000000000090000  x29 00000071a0073db0
    lr  00000071a123c5c4  sp  00000071a0073d50  pc  000000729d493bf8  pst 0000000020000000
backtrace:
      #00 pc 0000000000088bf8  /apex/com.android.runtime/lib64/bionic/libc.so (__memcpy+296) (BuildId: d2bad1502ac7810a2cce958ef2191244)
      #01 pc 00000000000b85c0  /data/app/~~d9P-afrEGRH5NQuVt8udAQ==/cbn.pl_srv-uJ42vp45jrgsu0b3hoFBtw==/lib/arm64/libffmpegJNI.so (Java_com_google_android_exoplayer2_ext_ffmpeg_FfmpegVideoDecoder_ffmpegRenderFrame+736) (BuildId: 5c3bb0e395d619abbb0a312094881fbf5d0cd75f)
      #02 pc 00000000000276fc  /data/app/~~d9P-afrEGRH5NQuVt8udAQ==/cbn.pl_srv-uJ42vp45jrgsu0b3hoFBtw==/oat/arm64/base.odex (art_jni_trampoline+204)
      #03 pc 0000000000133564  /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+548) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #04 pc 0000000000197e94  /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+204) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #05 pc 0000000000305328  /apex/com.android.art/lib64/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+376) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #06 pc 00000000003014b0  /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall<true, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+696) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #07 pc 000000000063918c  /apex/com.android.art/lib64/libart.so (MterpInvokeDirectRange+456) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #08 pc 000000000012dc14  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_direct_range+20) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #09 pc 0000000000397a10  /data/app/~~d9P-afrEGRH5NQuVt8udAQ==/cbn.pl_srv-uJ42vp45jrgsu0b3hoFBtw==/oat/arm64/base.vdex (com.google.android.exoplayer2.ext.ffmpeg.FfmpegVideoDecoder.renderToSurface+28)
      #10 pc 000000000063a368  /apex/com.android.art/lib64/libart.so (MterpInvokeVirtualQuick+1268) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #11 pc 0000000000131594  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_virtual_quick+20) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #12 pc 0000000000397c00  /data/app/~~d9P-afrEGRH5NQuVt8udAQ==/cbn.pl_srv-uJ42vp45jrgsu0b3hoFBtw==/oat/arm64/base.vdex (com.google.android.exoplayer2.ext.ffmpeg.FfmpegVideoRenderer.renderOutputBufferToSurface+8)
      #13 pc 000000000063a368  /apex/com.android.art/lib64/libart.so (MterpInvokeVirtualQuick+1268) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #14 pc 0000000000131594  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_virtual_quick+20) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #15 pc 0000000000467aa6  /data/app/~~d9P-afrEGRH5NQuVt8udAQ==/cbn.pl_srv-uJ42vp45jrgsu0b3hoFBtw==/oat/arm64/base.vdex (com.google.android.exoplayer2.video.DecoderVideoRenderer.renderOutputBuffer+150)
      #16 pc 000000000063a368  /apex/com.android.art/lib64/libart.so (MterpInvokeVirtualQuick+1268) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #17 pc 0000000000131594  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_virtual_quick+20) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #18 pc 00000000004671e2  /data/app/~~d9P-afrEGRH5NQuVt8udAQ==/cbn.pl_srv-uJ42vp45jrgsu0b3hoFBtw==/oat/arm64/base.vdex (com.google.android.exoplayer2.video.DecoderVideoRenderer.processOutputBuffer+322)
      #19 pc 0000000000636060  /apex/com.android.art/lib64/libart.so (MterpInvokeDirect+1164) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #20 pc 000000000012d914  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_direct+20) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #21 pc 0000000000466dcc  /data/app/~~d9P-afrEGRH5NQuVt8udAQ==/cbn.pl_srv-uJ42vp45jrgsu0b3hoFBtw==/oat/arm64/base.vdex (com.google.android.exoplayer2.video.DecoderVideoRenderer.drainOutputBuffer+140)
      #22 pc 0000000000636060  /apex/com.android.art/lib64/libart.so (MterpInvokeDirect+1164) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #23 pc 000000000012d914  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_direct+20) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #24 pc 0000000000467994  /data/app/~~d9P-afrEGRH5NQuVt8udAQ==/cbn.pl_srv-uJ42vp45jrgsu0b3hoFBtw==/oat/arm64/base.vdex (com.google.android.exoplayer2.video.DecoderVideoRenderer.render+124)
      #25 pc 00000000006354cc  /apex/com.android.art/lib64/libart.so (MterpInvokeInterface+1840) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #26 pc 000000000012da14  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_interface+20) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #27 pc 000000000035a4fa  /data/app/~~d9P-afrEGRH5NQuVt8udAQ==/cbn.pl_srv-uJ42vp45jrgsu0b3hoFBtw==/oat/arm64/base.vdex (com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork+202)
      #28 pc 0000000000636060  /apex/com.android.art/lib64/libart.so (MterpInvokeDirect+1164) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #29 pc 000000000012d914  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_direct+20) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #30 pc 0000000000358b8c  /data/app/~~d9P-afrEGRH5NQuVt8udAQ==/cbn.pl_srv-uJ42vp45jrgsu0b3hoFBtw==/oat/arm64/base.vdex (com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage+440)
      #31 pc 00000000006354cc  /apex/com.android.art/lib64/libart.so (MterpInvokeInterface+1840) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #32 pc 000000000012da14  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_interface+20) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #33 pc 0000000000623c4c  [anon:dalvik-classes2.dex extracted in memory from /system/framework/framework.jar!classes2.dex] (android.os.Handler.dispatchMessage+24)
      #34 pc 0000000000633b38  /apex/com.android.art/lib64/libart.so (MterpInvokeVirtual+1440) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #35 pc 000000000012d814  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_virtual+20) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #36 pc 000000000064d592  [anon:dalvik-classes2.dex extracted in memory from /system/framework/framework.jar!classes2.dex] (android.os.Looper.loop+498)
      #37 pc 00000000006368c0  /apex/com.android.art/lib64/libart.so (MterpInvokeStatic+1120) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #38 pc 000000000012d994  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_static+20) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #39 pc 000000000062470c  [anon:dalvik-classes2.dex extracted in memory from /system/framework/framework.jar!classes2.dex] (android.os.HandlerThread.run+56)
      #40 pc 00000000002f7e1c  /apex/com.android.art/lib64/libart.so (art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.8987581780827286127)+268) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #41 pc 0000000000622510  /apex/com.android.art/lib64/libart.so (artQuickToInterpreterBridge+796) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #42 pc 000000000013cff8  /apex/com.android.art/lib64/libart.so (art_quick_to_interpreter_bridge+88) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #43 pc 0000000000133564  /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+548) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #44 pc 0000000000197e94  /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+204) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #45 pc 000000000052aefc  /apex/com.android.art/lib64/libart.so (art::(anonymous namespace)::InvokeWithArgArray(art::ScopedObjectAccessAlreadyRunnable const&, art::ArtMethod*, art::(anonymous namespace)::ArgArray*, art::JValue*, char const*)+104) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #46 pc 000000000052c0fc  /apex/com.android.art/lib64/libart.so (art::JValue art::InvokeVirtualOrInterfaceWithJValues<art::ArtMethod*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, art::ArtMethod*, jvalue const*)+440) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #47 pc 0000000000579474  /apex/com.android.art/lib64/libart.so (art::Thread::CreateCallback(void*)+1272) (BuildId: 4058c54ceee4b6137f99348d05523753)
      #48 pc 00000000000f4204  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+64) (BuildId: d2bad1502ac7810a2cce958ef2191244)
      #49 pc 000000000008ec64  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: d2bad1502ac7810a2cce958ef2191244)
** Receiver (svc) OnReceive **
*** Service (svc) Create ***

The same code I using works well on Android Emulator (x86) but don't work in my phone (Redmi K20 Pro) and the car Android Unit (Android 8).

Edit:

If use this code: Engine.Initialize("player", True, True, False) it works, but Engine.Initialize("player", True, True, True) it does crash, so seems a problem with the FFMPEG Video decoder. Maybe some library is missing? or wrong arquitecture? because it works in a x86 emulator.
Until Exoplayer support ffmpeg video decoder officially. i may work on compatability between ffmpeg jni and Exoplayer source in the next week end. Hopefully those streams will be up for testing purposes.
Note : armeabi-v7a, arm64-v8a,x86_64 x86 are supported in addoffmpeg-release.
 
Last edited:

Zero7

Member
Hi @Addo,

There's another weird bug when loading a new stream. For eg, if you prepare() a TS stream and then, load another one it always show this error:

B4X:
[UI_player_Error] Crash = source.UnrecognizedInputFormatException: None of the available extractors (FlvExtractor, FlacExtractor, WavExtractor, FragmentedMp4Extractor, Mp4Extractor, AmrExtractor, PsExtractor, OggExtractor, TsExtractor, MatroskaExtractor, AdtsExtractor, Ac3Extractor, Ac4Extractor, Mp3Extractor, AviExtractor, JpegExtractor) could read the stream.
If I load the same last stream again, it plays without a problem. I cannot find a workaround for that than wait a second or two before prepare another stream.

So, the only way to make it working is load the same stream two times (one returns error and not play and the second load works ok).

My code to load a new stream:

B4X:
Sub MP_PlayStream(media As FileStruct)
    Try
    If Player.InitPlayer Then
        ToLog("MP_PlayStream", "URL: " & media.url & ", title: " &  media.name)
        Player.Media = media
        Player.Engine.Stop
        'Sleep(1000) some kind of fix.

        Player.Engine.Prepare(Player.Engine.CreateuriSource(media.url))
    
        Player.PlayingType = PLAYING_STREAM
        Player.Engine.Play
        Player.IsPlaying = True
        
        CallSub3(FullScreen, "SetOSD", Player.Media.Name, 8)

    End If
    Catch
        ToLog("MP_PlayStream", "Crash = " & LastException)
        Player.IsPlaying = False
    End Try

End Sub
 

Addo

Well-Known Member
Licensed User
Hi @Addo,

There's another weird bug when loading a new stream. For eg, if you prepare() a TS stream and then, load another one it always show this error:

B4X:
[UI_player_Error] Crash = source.UnrecognizedInputFormatException: None of the available extractors (FlvExtractor, FlacExtractor, WavExtractor, FragmentedMp4Extractor, Mp4Extractor, AmrExtractor, PsExtractor, OggExtractor, TsExtractor, MatroskaExtractor, AdtsExtractor, Ac3Extractor, Ac4Extractor, Mp3Extractor, AviExtractor, JpegExtractor) could read the stream.
If I load the same last stream again, it plays without a problem. I cannot find a workaround for that than wait a second or two before prepare another stream.

So, the only way to make it working is load the same stream two times (one returns error and not play and the second load works ok).

My code to load a new stream:

B4X:
Sub MP_PlayStream(media As FileStruct)
    Try
    If Player.InitPlayer Then
        ToLog("MP_PlayStream", "URL: " & media.url & ", title: " &  media.name)
        Player.Media = media
        Player.Engine.Stop
        'Sleep(1000) some kind of fix.

        Player.Engine.Prepare(Player.Engine.CreateuriSource(media.url))
  
        Player.PlayingType = PLAYING_STREAM
        Player.Engine.Play
        Player.IsPlaying = True
      
        CallSub3(FullScreen, "SetOSD", Player.Media.Name, 8)

    End If
    Catch
        ToLog("MP_PlayStream", "Crash = " & LastException)
        Player.IsPlaying = False
    End Try

End Sub
If this error occurred in a simple ready to run project, please attach it with the used media streams URL. So i can do some tests on the targeted stream that you are trying to play that cause such error. Its obvious from the error that the type of played stream cannot be handled by the mentioned extractors.
 
Last edited:

Zero7

Member
Its obvious from the error that the type of played stream cannot be handled bybthe mentioned extractors.
Really it can handle by the extractors, because the same stream URL sometimes play it, sometimes not.

Sounds like it need some time before .prepare() new stream for make it working, but this work should be done internally if is needed.

I did a manual test with buttons:

Button1 -> MP_PlayStream("http://xxxx/ch1", "channel1") -> it plays stream well.
Button2 -> player.Stop -> stop play stream
Button3 -> MP_PlayStream("http://xxxx/ch2", "channel2") -> it plays stream well.

but if I did this don't work:

Button1 -> MP_PlayStream("http://xxxx/ch1", "channel1") -> it plays stream well.
Button 3 ->MP_PlayStream("http://xxxx/ch2", "channel2") -> fails to play stream, it return the extractors error.

Note that I not using the playlist system of ExoPlayer (I have my own system of playlist) so I always use the prepare() method for every new stream I want to play... I don't know if this is important.

Anyway, I can try to build a basic proyect that reproduces the error for you.
 

Zero7

Member
Really it can handle by the extractors, because the same stream URL sometimes play it, sometimes not.

Sounds like it need some time before .prepare() new stream for make it working, but this work should be done internally if is needed.

I did a manual test with buttons:

Button1 -> MP_PlayStream("http://xxxx/ch1", "channel1") -> it plays stream well.
Button2 -> player.Stop -> stop play stream
Button3 -> MP_PlayStream("http://xxxx/ch2", "channel2") -> it plays stream well.

but if I did this don't work:

Button1 -> MP_PlayStream("http://xxxx/ch1", "channel1") -> it plays stream well.
Button 3 ->MP_PlayStream("http://xxxx/ch2", "channel2") -> fails to play stream, it return the extractors error.

Note that I not using the playlist system of ExoPlayer (I have my own system of playlist) so I always use the prepare() method for every new stream I want to play... I don't know if this is important.

Anyway, I can try to build a basic proyect that reproduces the error for you.
I cannot reproduce it with other streams, just with streams that comes from enigma2 server. Seems that something is cached in between first and second stream that makes the second one to get corrupted and then report an error (extractors). If I wait some seconds after player.stop it works without crash.

There's any kind of flush buffer or something in exoplayer code?
 

Addo

Well-Known Member
Licensed User
I just sent you a sample project, check PM.
I just looked at your example and it is working fine if you press on stream1 and stream2 in normal case. in case you are clicking too fast that way called bad design.. ExoPlayer already take care of threading aside from that is it safe to call most of its functions on the main application thread aside from that you need to take care of the methods you are using and wait for the expected method to be finish .

that's why I released a new update to extend the b4a wrapper and adding more events to give you the ability to read whats going on during each method you call.

New Update 1.70
added a new events :

  • updated the library to the latest Exoplayer version 2.18.5.
  • Added a new event : IDLE
  • Added a new Event : Buffering
download the new additional library AARS to use the latest exoPlayer update.
 

Zero7

Member
I just looked at your example and it is working fine if you press on stream1 and stream2 in normal case. in case you are clicking too fast that way called bad design.. ExoPlayer already take care of threading aside from that is it safe to call most of its functions on the main application thread aside from that you need to take care of the methods you are using and wait for the expected method to be finish .

that's why I released a new update to extend the b4a wrapper and adding more events to give you the ability to read whats going on during each method you call.

New Update 1.70
added a new events :

  • updated the library to the latest Exoplayer version 2.18.5.
  • Added a new event : IDLE
  • Added a new Event : Buffering
download the new additional library AARS to use the latest exoPlayer update.
Hi,

I just checked 1.70 and I still reproduce the issue easily, not need to do change too fast from one to another. Press stream1, wait until is playing video and then press stream2. It will crash. I also check Idle and buffering for a clue for what is happening...

Please check this video: https://mega.nz/file/gwQxyaZD#zGadMlw2Hcxhtgoy1HSar6WkbT1rKZjTzQjY2MYTDlQ
 
Last edited:

Addo

Well-Known Member
Licensed User
Hi,

I just checked 1.70 and I still reproduce the issue easily, not need to do change too fast from one to another. Press stream1, wait until is playing video and then press stream2. It will crash. I also check Idle and buffering for a clue for what is happening...

Please check this video: https://mega.nz/file/gwQxyaZD#zGadMlw2Hcxhtgoy1HSar6WkbT1rKZjTzQjY2MYTDlQ
Thats not what happened during my test i pressed stream 1 then waiting until its played then i pressed stream 2 and its playing normally.
 

Zero7

Member
Thats not what happened during my test i pressed stream 1 then waiting until its played then i pressed stream 2 and its playing normally.
Do it more than one time, stream1, stream2, stream1, stream2... and sooner or later should give you an error... at least, here happens (with mi9tpro, x86emulator and a generic android 8.0 device).
 
Top