Why isn’t this working?

Hi again.

Ok, this is confusing me.

First, the code:

for numberOfVideos = 0 to screenSaveMovieListWindow.ListBox1.RowCount -1
  
  f = New FolderItem(Listbox1.CellTextAt(numberOfVideos,0))
  
  If f <> Nil Then
    movieWindowForPlaying.MoviePlayer1.Movie = Movie.Open(f)
    movieWindowForPlaying.MoviePlayer1.Volume = app.moviePlayerVolume
    movieWindowForPlaying.MoviePlayer1.Play
    
  else
    
  end if
  
next numberOfVideos

What I want the code to do is get a list of the videos that are desired to be played. When I check, it sees all of the videos, with the full names and paths.

So far, so good.

Doing a debug, I see that the file exists, that the player indeed has the right file, but instead of playing that video and proceeding to the next, it falls through to each video until it gets to the end and only plays that one.

What am I not seeing?

Also, as a little side note, when I look at the movie Duration sometimes I see NaN. What is that?

Regards

MoviePlayer.Play is not a blocking call. It does not play the video before the next line of code runs. So what is happening is that each movie is starting and then it loops and starts the next movie playing (after stopping the existing one).

So that means, Ian I need to use a moviePlayer.Stop to manually stop the first video before I play the second?

No, starting a second should stop the first, as there is only a single Movie player.

MoviePlayer has a Stopped event that you could use to start playback of the next movie in the sequence.

Sorry for seeming dense, Ian, but when I have a second movie player, and start it with MoviePlayer2.Play, there is no change.

My code still falls through to the last video.

I have tried adding a timer to the window, so that it will run for the Duration of the video, and then stop the video, but when I debug, I see the Duration as NAN.0

Regards

Hi Julia.

How do you use the movie start / stop events?

Sorry for being slow on movieplayer.

Regards

Roughly speaking, if you move all the code you showed in your OP, into the Run event of a thread, then after the code which starts the movieplayer you should put:

me.Pause ()

Then, in the PlaybackStopped event, you put:

myThread.Resume ()

That’s the broad outline. You’ll prolly have to add extra code to handle edge cases and so on. You probably shouldn’t try pausing the main thread.

1 Like

Why use thread? As Ian mentioned, MoviePlayer isn’t blocking.

I assume you have one MoviePlayer, and it’s on a Window.

Add a handler for the Stopped (or Stop, depending on your Xojo version) event by right clicking on the MoviePlayer in the Navigator and selecting the event in the subsequent dialog:

In the event handler, do something like this to cycle through your movies (this example assumes MovieFiles() is an array of FolderItems that you’ve preloaded) :

You’ll also have to check to see if the movie is finished playing by checking the movie position in the PlaybackStopped event handler for the movie player. Otherwise if your user stops the movie it will skip to the next one.

I round it to avoid problems with doubles.

If Round(movieWindowForPlaying.Position) = Round(movieWindowForPlaying.Duration) Then
  //movie is done playing
  //load new movie
Else
  //user stopped the movie
End If

That’s fairly coarse, and will trigger the next movie when the previous one has up to 1.0 seconds of playback left.

I might do it this way:

var delta as double = m.Position - m.Duration
if abs(delta) < 0.1 then
 ' playback position is within 0.1 seconds of duration

Hi Tim.

When I go to add the Thread from the Library,I only get the option to RUN or UPDATETHEUI.

Never mind. No sleep + no coffee = can’t read. The movie start / stop events are events for the movie.

I’m taking 20 to saw wood.

Regards

As I said, you put the code from your OP into the Run event, adding the me.pause as noted.

Then you put the resume in the PlayBackStopped event of the moviePlayer.

So the Thread just “runs”?
Doesn’t have to be called or anything like that?

I am sorry I seem dense on this. I have gone through the example in Examples, Tim, but I’m not really getting the logic on what is happening.

Regards

1 Like

You have to start the thread by for example putting:

mythread.Start ()

in the Pressed event handler of a button. Then the thread runs when you click the button.

My advice is to look up the doc for Thread. Then you read all about the properties of a thread, what they’re for. Same with Methofds for the thread, and its event handlers. Then think about which of all of these you might use to solve your problem. Do the same for the doc for MoviePlayer.

You also need to think about what the app is you’re creating. A finished product? A toy app for testing purposes, to give you ideas for a real app later? And so on.

But reading the docs is always a good start.

Thanks Tim.

You might not believe this, but I DO read the documents, and open run / debug the examples.

Sometimes, and this is all on me, some things don’t “click”.
It took a long while for me to really clue into something that might have been simple for everyone else… that is database Encrypt and Decrypt.

I will continue to work on this, and advise.

As to what it is for. Once upon a time I had a screensaver that worked all the way up to Catalina OS, but then died due to changes in the OS.

I like having movies as a screensaver as I put on different aquarium ones that fasinate her for hours.

Regards.

Hi

I’d be tempted to do this with a Timer. Have the MoviePlayer update its status depending on whether it’s playing, finished, stopped etc. Then have the Timer check that status every 100 ms or whatever and it can determine what to do next - nothing if a movie is already playing; start playing the next movie if the current one has finished. I’m not sure what you’d gain with a thread here and as MoviePlayer is a UI element you might be getting close to a ThreadAccessingUIException.

Regards - Richard

Hi All.

Ok, after doing a little thinking, I ALMOST have the playback working.

I have created a method to call, and the only thing that isn’t happening is the continuation of playing.

Here is the method:

//for testing purposes only
MessageBox "app.PlayTheMovie row is: " + app.playTheMovie.ToString

// set the folder item, theMovie, to the row of the movie (or NEXT movie) to the appropriate listbox row.
app.theMovie =   New FolderItem(screenSaveMovieListWindow.Listbox1.CellTextAt(app.playTheMovie,0))

if app.theMovie <> NIL then //if the file exists…
  
  //for testing purposes only
  MessageBox "The movie we will play is : " + app.theMovie.Name + " . “
  
  //play the movie
  movieWindowForPlaying.MoviePlayer1.Play
  
else
  
  //for testing purposes only
  MessageBox "No movie found”
  
end if

In the movieplayer PlaybackStarting event:

movieWindowForPlaying.MoviePlayer1.AutoPlay = true
movieWindowForPlaying.MoviePlayer1.Movie = Movie.Open(app.theMovie)
movieWindowForPlaying.MoviePlayer1.HasController = FALSE
movieWindowForPlaying.MoviePlayer1.Volume = app.moviePlayerVolume

In the moviePlayer PlaybackStopped:

// advance to next listbox row

app.playTheMovie = app.playTheMovie + 1
app.theMovie =   New FolderItem(screenSaveMovieListWindow.Listbox1.CellTextAt(app.playTheMovie,0))

// for testing purposes only
MessageBox "The playback has stopped.”
MessageBox "The next movie being cued is : " + app.theMovie.Name


app.playAllMovies()

It tells me the movie is what I expect, but it NEVER starts.

Any ideas?

Regards

The PlayBackStarting event doesn’t fire until the movie has started, so it looks like on the first pass, this

will not have been executed yet so the MoviePlayer at that point has no movie assigned to its Movie property.

Hi Julia.

The only issue I have with your response (and I am probably wrong, so please be forgiving) is that when The button is pressed to start the screensaver (and I forgot to add that code so here it is…

// first find the size of screen I have
//height and width

//make it full screen
movieWindowForPlaying.FullScreen = TRUE
movieWindowForPlaying.MoviePlayer1.Height = DesktopDisplay.DisplayAt(0).Height
movieWindowForPlaying.MoviePlayer1.Width = DesktopDisplay.DisplayAt(0).width

// repeats the video playing from the beginning.
//movieWindowForPlaying.MoviePlayer1.AutoRepeat = TRUE

//allow the user to have sound or not
Select Case muteCheckBox.VisualState
  
Case DesktopCheckBox.VisualStates.Unchecked
  App.moviePlayerVolume = 100
  
case DesktopCheckBox.VisualStates.Checked
  App.moviePlayerVolume =0
  
case DesktopCheckBox.VisualStates.Indeterminate
  App.moviePlayerVolume = 50
  
End Select

//fire the method.
//send the number of movies selected to the method.  
app.playAllMovies()

I do get the first movie selected (or more accurately the movie in the listbox row 0, cell 0… and row 0 increments) to play.

Then when I hit the playback stopped event I see that the row variable I use is incremented, the method is called, and in the playback start I get the test message box saying the name of the next movie that will play.

It just never plays.
I’ve tried adding in the playbackstopped event

MoviePlayer1.Play

etc.

But it just doesn’t play.

Regards