This is really not a new library but a way to show how to to use VideoView optimized for orientation-change and make your VideoView-app behave more professionally.
I have seen many apps showing a VideoView in portrait-mode and when you change the orientation into landscape-mode, the video continues to play smoothly (without interruption) and at the same time the video is being resized properly from a smaller screen in order to fill up the screen properly. This works also in the other direction.
This behaviour is not easy to accomplish without using some complimentary code. Even fellow Android-developers using Android Studio/Eclipse have faced this problem.
I sat down and tried to find a solution it but it was not an easy task and it took me a lot of testing to get it working. With Android Studio it was easier but with B4A, I had to use a different approach and add some complementary code to get it working.
Therefore, I am happy to share this project with you which shows you how you can use a VideoView and change orientation making sure that:
1) video will not stop after orientation-change but will continue playing smoothly
2) video will resize to full screen in landscape and scale in the center in portrait-mode.
I am sharing the code here below. I have also attached the code as a sample-project where you will also find the requested xml-layout file necessary to get things working properly. Check also the changes I made to the Manifest. Please make sure to read my code-comments to understand better what I am doing.
If you make any improvements to the code, please share!
Thanks for reading.
I have seen many apps showing a VideoView in portrait-mode and when you change the orientation into landscape-mode, the video continues to play smoothly (without interruption) and at the same time the video is being resized properly from a smaller screen in order to fill up the screen properly. This works also in the other direction.
This behaviour is not easy to accomplish without using some complimentary code. Even fellow Android-developers using Android Studio/Eclipse have faced this problem.
I sat down and tried to find a solution it but it was not an easy task and it took me a lot of testing to get it working. With Android Studio it was easier but with B4A, I had to use a different approach and add some complementary code to get it working.
Therefore, I am happy to share this project with you which shows you how you can use a VideoView and change orientation making sure that:
1) video will not stop after orientation-change but will continue playing smoothly
2) video will resize to full screen in landscape and scale in the center in portrait-mode.
I am sharing the code here below. I have also attached the code as a sample-project where you will also find the requested xml-layout file necessary to get things working properly. Check also the changes I made to the Manifest. Please make sure to read my code-comments to understand better what I am doing.
If you make any improvements to the code, please share!
Thanks for reading.
B4X:
'*****************************************************************************************************************************************
' VideoView example optimized for orientation-change by moster67 (Mikael Osterhed) - 01/08/2016
' My thanks go to JordiCP and Erel for some useful code-snippets.
'This small project shows how you can use a VideoView and change orientation making sure that:
' 1) video will not stop after orientation-change but will continue playing smoothly
' 2) video will resize to full screen in landscape and scale in the center in portrait-mode.
'The fact that the video will not stop after orientation change is because we are using a special attribute
'in the manifest. This is done by inserting the following attribute in the manifest:
' SetActivityAttribute(Main, android:configChanges, "orientation|screenSize|smallestScreenSize|keyboard|keyboardHidden|navigation")
'Above attribute will make the code skip the onCreate method upon orientation-change. Note: This has some drawbacks though
'which we will resolve by using some specific code (see code-comments in the project).
'In order to resize the video properly after orientation-change has taken place, we are using an xml-layout based on FrameLayout.
'With this project I am providing an xml-layout called frame. In order to use this layout, we must use the XmlLayoutBuilder library
'which you can download from the B4A-forum.
'NOTE:
'If you are streaming content from the Internet, you must also add the following permission in the manifest:
' AddPermission(android.permission.INTERNET)
'
'Required libraries: Audio, JavaObject, XmlLayoutLibrary
'
'****************************************************************************************************************************************
#Region Project Attributes
#ApplicationLabel: vvxml
#VersionCode: 1
#VersionName:
'SupportedOrientations possible values: unspecified, landscape or portrait.
#SupportedOrientations: unspecified
#CanInstallToExternalStorage: False
'ensures that the res-folder (and the xml-layout) is read-only so that it cannot be deleted.
'alternatively you can set the xml-layout file as read-only
#CustomBuildAction: 1, c:\windows\system32\attrib.exe, +r res\*.* /s
#End Region
#Region Activity Attributes
#FullScreen: true
#IncludeTitle: false
#End Region
Sub Process_Globals
'These global variables will be declared once when the application starts.
'These variables can be accessed from all modules.
Dim timer1 As Timer
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 x As XmlLayoutBuilder
Private ActivityParent As JavaObject
End Sub
Sub Activity_Create(FirstTime As Boolean)
'* Code needed for the sub AfterChange. See comments in said sub.
Dim jo As JavaObject = Activity
jo.RunMethodJO("getContext", Null).RunMethodJO("getWindow", Null)
ActivityParent = jo.RunMethodJO("getParent", Null)
timer1.Initialize("Timer1",100)
'***********************************************************************************************
'Load the layout using XmlLayoutBuilder. You may need to download the library from the forum.
'I am providing an xml-layout based on FrameLayout. It must be placed in the layout-folder
'under Objects/res/. This layout ensures that the video will resize after an orientation change.
'If you have difficulties in understanding how the XmlLayoutBulder works, please then read the
'thread from where you downloaded it.
'***********************************************************************************************
x.LoadXmlLayout(Activity, "frame")
vv.Initialize("vv")
vv = x.GetView("surface")
Activity.Color = Colors.Black
vv.LoadVideo("http","http://www.storiesinflight.com/js_videosub/jellies.mp4")
vv.Play
End Sub
Sub Activity_Resume
End Sub
Sub Activity_Pause (UserClosed As Boolean)
End Sub
Sub vv_Complete
Log("Playing completed")
End Sub
Sub timer1_Tick
If vv.IsPlaying Then
CallSubDelayed(Me, "AfterChange")
End If
End Sub
Sub Activity_ConfigChanged()
'****************************************************************************************
'This code together with the java-snippet in this project detects a configuration-change
'Here I use the timer to call the sub AfterChange
'My testing showed that a delay of 100ms is sufficient to let the sub AfterChange
'be in a position to obtain the new activity values. It resulted also in a smooth
'orientation-change of the playing video.
'****************************************************************************************
Log("inside configsub")
timer1.Enabled = True
End Sub
Sub AfterChange
'******************************************************************************************************
'After a configuration-change, bypassing onCreate, it is difficult to get the new values
'of Activity Height and Activity Width. This code posted by Erel helps us to obtain the new values.
'******************************************************************************************************
Dim ajo As Panel = Activity
Dim width As Int = ActivityParent.RunMethod("getMeasuredWidth", Null)
Dim height As Int = ActivityParent.RunMethod("getMeasuredHeight", Null)
If width = 0 Or height = 0 Then Return
ajo.Width = width 'update the "activity" width and height
ajo.Height = height
Activity.Invalidate
vv.Width = width
vv.Height = height
'Log("AW=" & Activity.Width & " and AH=" & Activity.Height)
vv.Invalidate
timer1.Enabled = False
End Sub
#if JAVA
//This java-code will detect a configuration-change. We use it to trigger our event
//Activity_ConfigChanged in our B4A-code.
//Many thanks to JordiCP in the B4A-forum for this java-snippet!!
import android.content.res.Configuration;
import anywheresoftware.b4a.keywords.Common;
import android.view.WindowManager;
import android.content.Context;
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
processBA.raiseEvent(null, "activity_configchanged"); // trigger event in B4A-code
}
#end if
Attachments
Last edited: