B4J Question Get a video frame and display

lymey

Active Member
Licensed User
Longtime User
Hi!
I am trying to extract a frame from a video file and then display in an imageview. I am not very experienced in using java objects and am trying this code:
B4X:
Dim fc As 
      fc.Initialize                         
      fc.InitialDirectory = File.DirApp     
      fc.SetExtensionFilter("Video", Array As String("*.mp4"))
      fc.Title = "Select a Video File"
      fc.InitialFileName = mediaFile
      fc.InitialDirectory = File.DirApp
      VideoFile = fc.ShowOpen(MainForm)
      If VideoFile.Length = 0 Then Return
      Dim fileO As JavaObject
      fileO.InitializeNewInstance("java.io.File", Array As Object(VideoFile))
      VideoFile = fileO.RunMethod("getName", Null)
      VideoFolder = fileO.RunMethod("getPath", Null)
      VideoFolder = mediaFolder.Replace(VideoFile, "")
      'get a frame and display
      Dim jo_1, mmr As JavaObject
      Dim bmp As Image
'class not found exception on the following line:
      mmr = jo_1.InitializeNewInstance("javafx.scene.media.MediaMetadataRetriever", Array As Object())
      mmr.RunMethod("setDataSource", Array As Object(VideFolder, VideoFile))
      bmp=mmr.RunMethod("getFrameAtTime", Array As Object(1))
I get a 'Class Not Found' exception at the line indicated.
Can I have some help with the correct code for extracting a video frame using B4J.
Thank you!
 

Daestrum

Expert
Licensed User
Longtime User
Is this for B4J or B4A as there is no such thing (as far as I am aware) as MediaMetadataRetriever in JavaFX (getFrameAtTime doesn't exist either) they are android classes.
 
Upvote 0

lymey

Active Member
Licensed User
Longtime User
Is this for B4J or B4A as there is no such thing (as far as I am aware) as MediaMetadataRetriever in JavaFX (getFrameAtTime doesn't exist either) they are android classes.
Yes this is for B4J. How would I get a video frame using B4J?
 
Upvote 0

lymey

Active Member
Licensed User
Longtime User
You might be able to get a snapshot using my VLC(J) wrapper:
https://www.b4x.com/android/forum/t...ediaplayer-in-your-program-app.77098/#content

I believe there is a method named "saveSnapshot" but I don't remember if it is included in the wrapper. If not, you can probably add it using JavaObject (see the GetFps-method in the demo-project).
Thanks, I will take a look at it. Ideally I would like to use the 'native' media player if possible. I had assumed that if it was possible using B4A it should be possible in B4J too.
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
Here's an example of what you wanted to achieve(excuse the code being untidy, it's late and my brain is tired :) )
B4X:
Sub Process_Globals
    Private fx As JFX
    Private MainForm As Form
    Dim mp As MediaPlayer
    Dim mp1 As JavaObject
    Dim Duration As JavaObject
    Dim iv As ImageView
    Dim snapshotParams As JavaObject
    Dim form2 As Form
    Dim b As Button
End Sub

Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    MainForm.Show
    b.Initialize("b") ' button to trigger snapshot
    b.Text = "snapshot"
    form2.Initialize("",400,400) ' form to display the snapshot image
    form2.SetOwner(MainForm)
    mp.Initialize("mp",File.GetUri("the directory tree to the file","the name of the file.mp4")) ' address of file  dir,filename
    mp1.InitializeNewInstance("javafx.scene.media.MediaView",Array(mp))
    Duration.InitializeNewInstance("javafx.util.Duration",Array(1000.00d*60.00D*5.00D)) ' 5 minutes into film
    MainForm.RootPane.AddNode(mp1,10,50,400,300)
    MainForm.RootPane.AddNode(b,0,0,100,30)
    asJO(mp).RunMethod("setStartTime",Array(Duration)) ' jump to my start time
    mp.play '  play the film
End Sub
Sub b_Click ' sub to grab snapshot
    Dim im As JavaObject
    im.InitializeNewInstance("javafx.scene.image.WritableImage",Array(200,100)) ' snapshot image 200,100
    snapshotParams.InitializeNewInstance("javafx.scene.SnapshotParameters",Null) ' create default params
    im = mp1.RunMethod("snapshot",Array(snapshotParams,Null))
    iv.Initialize("") ' the imageview
    iv.SetImage(im) ' load into imageview
    form2.RootPane.AddNode(iv,0,0,200,100) ' add imageview to new form
    form2.show ' show the form
End Sub

Sub asJO(o As JavaObject)As JavaObject
    Return o
End Sub

'Return true to allow the default exceptions handler to handle the uncaught exception.
Sub Application_Error (Error As Exception, StackTrace As String) As Boolean
    Return True
End Sub
 
Upvote 0

lymey

Active Member
Licensed User
Longtime User
Here's an example of what you wanted to achieve(excuse the code being untidy, it's late and my brain is tired :) )
B4X:
Sub Process_Globals
    Private fx As JFX
    Private MainForm As Form
    Dim mp As MediaPlayer
    Dim mp1 As JavaObject
    Dim Duration As JavaObject
    Dim iv As ImageView
    Dim snapshotParams As JavaObject
    Dim form2 As Form
    Dim b As Button
End Sub

Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    MainForm.Show
    b.Initialize("b") ' button to trigger snapshot
    b.Text = "snapshot"
    form2.Initialize("",400,400) ' form to display the snapshot image
    form2.SetOwner(MainForm)
    mp.Initialize("mp",File.GetUri("the directory tree to the file","the name of the file.mp4")) ' address of file  dir,filename
    mp1.InitializeNewInstance("javafx.scene.media.MediaView",Array(mp))
    Duration.InitializeNewInstance("javafx.util.Duration",Array(1000.00d*60.00D*5.00D)) ' 5 minutes into film
    MainForm.RootPane.AddNode(mp1,10,50,400,300)
    MainForm.RootPane.AddNode(b,0,0,100,30)
    asJO(mp).RunMethod("setStartTime",Array(Duration)) ' jump to my start time
    mp.play '  play the film
End Sub
Sub b_Click ' sub to grab snapshot
    Dim im As JavaObject
    im.InitializeNewInstance("javafx.scene.image.WritableImage",Array(200,100)) ' snapshot image 200,100
    snapshotParams.InitializeNewInstance("javafx.scene.SnapshotParameters",Null) ' create default params
    im = mp1.RunMethod("snapshot",Array(snapshotParams,Null))
    iv.Initialize("") ' the imageview
    iv.SetImage(im) ' load into imageview
    form2.RootPane.AddNode(iv,0,0,200,100) ' add imageview to new form
    form2.show ' show the form
End Sub

Sub asJO(o As JavaObject)As JavaObject
    Return o
End Sub

'Return true to allow the default exceptions handler to handle the uncaught exception.
Sub Application_Error (Error As Exception, StackTrace As String) As Boolean
    Return True
End Sub
That's a great help...thank you very much! I hope it didn't keep you up too late!
 
Upvote 0
Top