Android Question VideoView Buffer Loading Percentage And VideoView Controls Skin

ronovar

Active Member
Licensed User
Longtime User
If is possible to display buffer percentage when loading from url file? For Example i load file using VideoView0.LoadVideo("MYURL\FILE.AVI" and would like when buffer is read to display on screen perctange of loaded buffer. Like on picture attached.

And the second question is if is possible to skin controls for VideoView bottom bar...i would like to change pause play rewind buttons and progress bar with png images to make custom skin...some example code will be great.

Thanks.

http://widgets.better2web.com/loader/

Just Press Run Loader Button..this i would like to make for VideoView...Thanks
 

ronovar

Active Member
Licensed User
Longtime User
I think it is possible but if You can please write here how to call thiese API to android and function will return integer value from 0 to 100 in perctange.

I found that using reflection library is possible so if You can give example code so that i can learn how to call android java code using api..here is how one member of this forum calls function:

B4X:
Dim MP AsMediaplayer

 MP.Initialize
 Dim R AsReflector
 R.Target=MP
 R.Target=R.GetField("mp")
 AudioSessionID=R.RunMethod("getAudioSessionId")

So i need this to get value from this function: onBufferingUpdate(MediaPlayer mp, int percent)

I dont know how to pass parameters MediaPlayer mp and int percent to R.RunMethod for Reflector.

Here is API description:
http://developer.android.com/refere...l#onBufferingUpdate(android.media.MediaPlayer, int)
 
Upvote 0

ronovar

Active Member
Licensed User
Longtime User
Thanks...Can You give example code how to do that..i im not familiar with JavaObject...if You can post example..so that i can learn how to do that with JavaObject library. Thanks.
 
Upvote 0

ronovar

Active Member
Licensed User
Longtime User
I try this it compiles code run but i dont see any output in log values from 0 to 100. Do i have write code wrong?

B4X:
Dim jo As JavaObject
jo.InitializeStatic("android.media.MediaPlayer")
jo.CreateEvent("android.media.MediaPlayer.OnBufferingUpdateListener", "setOnBufferingUpdateListener", 0)

I think that it will be great to create here on forum tutorial how to write void functions from android api that returns functions api values and how to set api values using javaobject library...this we miss alot.

Thanks.
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
when you create a listener in java then you need to create a method which will be called when the listener get called
I believe you need to create a even-sub too but i´m not sure if it works when you simply create a sub named (based on this)
B4X:
sub  onBufferingUpdate (mp As Mediaplayer, percent As int)
    log("onBufferingUpdate("&percent&")")
end sub
 
Upvote 0

ronovar

Active Member
Licensed User
Longtime User
I try to add this Sub and add to activity create above code from javaobject it compiles..but i im getting nothing from my log....maybe i need to pass two parameters to onBufferingUpdate - MediaPlayer and Percent You pass only percent...thans for helping but we need more code to return percent.
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
maybe i need to pass two parameters to onBufferingUpdate
usually a LISTENER is called from the system and it GIVES this parameters...

So something is wrong here but i dont know what. Maybe Erel (or any other who can ;-)) can help us out here to give us a useful hint :)
 
Upvote 0

ronovar

Active Member
Licensed User
Longtime User
Yes...thatns DonManfred for helping...i think i wrong wrote JavaObject code...so it don't run listener...but i don't know how to use JavaObject...so that why i ask for help Erel and other who know how to use JavaObject library...to show us examples...from android api how to call function and read returned parameters and how to send parameters to android api and read back returned value...this way i can create module and upload it here so that videoview wrapper have all functions like android api that is programmed in eclipse.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Upvote 0

ronovar

Active Member
Licensed User
Longtime User
Thanks Erel....i try this code it compiles without error...but when code is run i get this error in log:

LastException java.lang.ClassCastException: $Proxy0 cannot be cast to java.lang.Object[]
 
Upvote 0

moster67

Expert
Licensed User
Longtime User
I tried using OnBuffering with an app I wrote in Android Studio but the buffer indicator was very fast and reached 100% very quickly so it was difficult to use.

I ended up using another solution (requires API >= 17 - Jelly Bean) which uses the onInfo event in combination with the onPrepared event. In this way, I show a progressbar (Indeterminate = true) until the video starts (onPrepared event) and in case of buffering I make it visible again (onInfo event). This works fine for me. It is easier to explain showing you example code with B4A (see below). I hope this will help.

B4X:
#Region  Project Attributes
    #ApplicationLabel: B4A vvbuff
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.

End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
    Dim vv As VideoView
    Dim myprogressbar As ProgressBar
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    'Activity.LoadLayout("Layout1")
   vv.Initialize("vv")
   Activity.AddView(vv, 0, 0, 300dip, 300dip)
   myprogressbar.Initialize("")
   myprogressbar.Indeterminate = True
   Activity.AddView(myprogressbar,0,0,200dip,200dip)
   myprogressbar.Visible = True
   AddInfoHandler(vv,"VVInfo")
   AddPreparedHandler(vv,"VVPrepared")
   vv.LoadVideo("http", "http://download.wavetlan.com/SVV/Media/HTTP/BlackBerry.3gp")
End Sub

Sub Activity_Resume
End Sub

Sub Activity_Pause (UserClosed As Boolean)
End Sub

Sub vv_Complete
    Log("Playing completed")
End Sub

Sub AddPreparedHandler(v As VideoView, EventName As String)
   Dim jo As JavaObject = v
   Dim e As Object = jo.CreateEventFromUI("android.media.MediaPlayer.OnPreparedListener", EventName, True)
   jo.RunMethod("setOnPreparedListener", Array(e)) 
End Sub

Sub VVPrepared_Event (MethodName As String,Args() As Object) As Object
   Log("Prepared")
   myprogressbar.Visible = False
   vv.Play
   Return Null
End Sub

Sub AddInfoHandler(v As VideoView, EventName As String)
   Dim jo As JavaObject = v
   Dim e As Object = jo.CreateEventFromUI("android.media.MediaPlayer.OnInfoListener", EventName, True)
   jo.RunMethod("setOnInfoListener", Array(e))
End Sub

Sub VVInfo_Event (MethodName As String,Args() As Object) As Object
  Dim what As Int = Args(1)
  Log("info = constant value " & what)
  If what = 701 Then 'MEDIA_INFO_BUFFERING_START
      Log("my bufferindicator.visible = true")
    myprogressbar.Visible = True
  Else If what = 702 Then 'MEDIA_INFO_BUFFERING_END
      Log("my bufferindicator.visible = false")
     myprogressbar.Visible = False
  End If
  'Dim extra As Int = Args(2)
  Return Null
End Sub
 
Last edited:
Upvote 0

moster67

Expert
Licensed User
Longtime User
Hmm, I wrote above code in the office testing on an emulator and it works fine in debug-mode. However, just tested it out of curiosity in release mode and note that I always get "Can't play video" (i/o error). If I run it again in debug-mode it works...

Erel, could this be related to using the JavaOject and its methods? Are you aware of any circumstances when the JavaObject does not work correctly in Release mode? Any ideas?
 
Upvote 0

moster67

Expert
Licensed User
Longtime User
Weird...can't really test now since the Boss is around :eek:

I will test on a real device when I get back home although I find it strange. Anyway, if anyone else would like to test, just copy the code into an empty project (adding audio and javaobject libraries).
 
Upvote 0

ronovar

Active Member
Licensed User
Longtime User
Weird...can't really test now since the Boss is around :eek:

I will test on a real device when I get back home although I find it strange. Anyway, if anyone else would like to test, just copy the code into an empty project (adding audio and javaobject libraries).

Thanks for code...i try it now and getting this error when running api in debug mode:

LastException java.lang.RuntimeException: Method: setOnInfoListener not found in: android.widget.VideoView

Here is project file for B4A
 

Attachments

  • BufferUpdate.zip
    6.6 KB · Views: 431
Upvote 0

moster67

Expert
Licensed User
Longtime User
It seems like the onInfoListener was only introduced with API 17 and not API 9 as mentioned in my code example. I have corrected the post and thus API >=17 (Jelly Bean) is needed. Anyway, I think most devices of the last 2-3 years are running Jelly Bean or newer so it shouldn't be a problem.

However, this still does not explain why the code sample I posted works fine in debug-mode (legacy and rapid) but not in release mode? I tested on a real device as well but with the same result. Maybe Erel would like to look into it? ;)

Anyway, I made another library of the videoview and added the following events: Prepared, Error and Info. Also this wrapper requires API >=17 since the OnInfoListener is included. I called it videoviewplus (great innovation/fantasy in selecting a name) ;) The library has been posted here:

https://www.b4x.com/android/forum/threads/videoviewplus-some-events-added.49329/

Attached is a sample project to use with the library. Oh yes, it works in release-mode as well.
 

Attachments

  • vvbufftest.zip
    6.5 KB · Views: 464
Last edited:
Upvote 0
Top