Looping part of a script after a certain time elapsed

This topic contains 14 replies, has 4 voices, and was last updated by Profile photo of Dan Potter Dan Potter 3 months ago.

  • Author
    Posts
  • #60294
    Profile photo of Scott Windmiller
    Scott Windmiller
    Participant

    I am building a PS Gui Jukebox/Music Player using the iTunes ComObject (New-Object -ComObject iTunes.Application). I am able to pull in alot of info, play files and most of what I need to do.

    Where I am struggling is with displaying the current playing track (from iTunes) and having it change when the song changes. I am able to display the current track when I play it without issue like this:

    $currentlyPlaying = {
    	$current= $itunes.CurrentTrack | Select Name, Artist, Album
    	$textboxCurrentArtist.Text = $current.Artist
    	$textboxCurrentTrack.Text = $current.Name
    	$textboxCurrentAlbum.Text = $current.Album
    }

    When the current song finishes I don't know of a way to have it "re-check" for the new song. I guess I could loop the "check" every second or so but I assume that's a bad idea 🙂
    One of the tracks properties is the length of the song, could I use that to wait until that time elapsed then perform the check again?

    Thanks,
    Scott
    I am still very new to PS but am trying to learn as I go along and using this project to learn.

    Can someone help with with an example of how I could do this (I learn better with examples) or is there a better way?

    Thanks,
    Scott

  • #60297
    Profile photo of Anthony
    Anthony
    Participant

    I could write something entirly for you but if you actually want to learn this should give you a starting point

    $itunes = New-Object -ComObject iTunes.Application
    
    $current = $itunes.CurrentTrack | Select Name, Artist, Album, Duration
    
    while ($itunes.PlayerPosition -le $current.Duration) {
      Write-Verbose -Message "Still playing, current duration is $($itunes.PlayerPosition) out of $($current.duration)" -Verbose
      start-sleep -Seconds 1
    }

    Logically what I would be trying to do is:

    Get the current track and the current duration of the track
    Get the itunes current player position
    Check if the player position is within the duration of the current track
    If it is keep looping until it isn't
    Once it isn't refresh the $current variable with the new information
    Start the entire process again

    You should be able to accomplish this with some if statements and a while loop.

    Here is an example of something similar I do with IE

  • #60307
    Profile photo of Scott Windmiller
    Scott Windmiller
    Participant

    Thanks, this does help but I have a few questions.

    Not knowing much about scripting does it hurt to have this looping every second to check on a constant basis? Me being a newbie I guess I thought by looping something and checking every second would be some sort of resource hog, or is this just how things are done 🙂

    My second question is, if I am going to loop every second to see if the track is over then why would I not just "check the current track" every second and forget about the time?

    Sorry I am not doubting what you are saying I am just so new to scripting and programming I just don't know how things are done properly.

    Thanks for taking the time to help me!
    Scott

  • #60313
    Profile photo of Dan Potter
    Dan Potter
    Participant

    I don't have it in a gui but feel free to modify to suit your needs.

    
    function play-itunes {
    	
    	param($genre)
    	
    	start-job -name itunes -scriptblock {
    		
    		param($genre)
    		
    		$iTunes = New-Object -ComObject iTunes.Application
    		$LibrarySource = $iTunes.sources.ItemByName('Library')
    		$libraryplaylist = $librarysource.playlists.itembyname('Dan''s Music')
    		$category = $libraryplaylist.search($genre, $this.ITPlaylistSearchField.ITPlaylistSearchFieldgenre)
    		$songstoplay =  $category | sort {get-random}
    		
    		foreach ($song in $songstoplay) {
    			
    			$song.play()
    			
    			$host.ui.rawui.windowtitle = "Now playing -- " + $song.name
    			
    			$total = $song.duration + 5
    			
    			start-sleep -seconds $total
    			
    			$host.ui.rawui.windowtitle = "Windows Powershell"
    			
    		}
    		
    		
    	} -argumentlist $genre | out-null
    	
    	
    	if (!($timer)) {
    		
    		$timer = new-object timers.timer
    		
    		$action = {
    			
    			$Global:windowtitle = receive-job -name itunes -keep
    		}
    		
    		$timer.Interval = 10000
    		
    		$Timer.Enabled = $True
    		
    		Register-ObjectEvent -InputObject $timer -EventName elapsed `
    							 –SourceIdentifier ItunesTimer -Action $action | Out-Null
    		
    		$Timer.Start()
    		
    		
    	}
    	
    }
    
    
    
  • #60388
    Profile photo of Scott Windmiller
    Scott Windmiller
    Participant

    Wow! Thanks so much!

    I will try this out asap, I am pretty sure I understand most of this.

    Would you happen to have any other iTunes PS scripts I could look at?

    The other thing I was having trouble with is displaying the album art for the currently playing song, either by using the artwork built in to the tag or by querying a website to find the artwork.

    Thanks again!
    Scott

  • #60390
    Profile photo of Dan Potter
    Dan Potter
    Participant

    That's the only one. I wanted something simple to work while I'm in the shell. Replacing gui for gui didn't work for me as the api opens itunes anyway=D

    Just remember start-sleep is going to freeze your form unless you put it in a job. Do you have Sapien PS studio?

  • #60399
    Profile photo of Scott Windmiller
    Scott Windmiller
    Participant

    Thanks for writing back!
    I am trying to replace the GUI to a point because we are using this on a touchscreen mounted in the wall and the iTunes interface is just too small to use like this.
    I wanted to dumb it down a bit and just do the basics for us. I have tried a bunch a different jukebox frontends and just figured it would better to try to make my own 🙂
    Thanks for the tip on the Job, it makes sense but I would not have realized that right away since I am still fairly new to PS.
    I am using Sapien for all of this. The album artwork and the current track refresh is what is holding me back right now, but I think with your post I may be able to figure that one out. Now I just have to figure out the artwork.

    Thanks for all your input!!
    Scott

  • #60402
    Profile photo of Dan Potter
    Dan Potter
    Participant

    You just made me reminisce about when customizing winamp was all the rage:D Sapien will help tremendously. Look into the job tracker, timer and picturebox controls. Not to drive you away from here but I'm active over on there forums as well.

  • #60405
    Profile photo of Scott Windmiller
    Scott Windmiller
    Participant

    Thanks and yeah I post there too! I have just received so much great help here and since my original post was not GUI specific I figured I would post here first.
    I will definitely look into those controls, I hope to try all of this out later on tonight or tomorrow.

    Thanks for everything!
    Scott

  • #60598
    Profile photo of Dan Potter
    Dan Potter
    Participant

    This is what I have so far.

    Untitledupload gif from url

    I'm currently in a battle with the play position. Unfortunate the itunes native gui keeps the current song order so it'll go back to the next after the last played if you skip forward or backward.

    https://github.com/danSpotter/Powershell/blob/master/psitunes/psitunes.ps1

  • #60603
    Profile photo of Scott Windmiller
    Scott Windmiller
    Participant

    Wow this looks great. So weird that you mention that, I was just struggling with this for the last 2 days. The only option I see to play from a playlist is playfirsttrack. If there was a way to select a track in iTunes then you should be able to use the Index number of the original track in the playlist and just add 1.
    I plan to look through your code tonight, thanks a ton for posting it.

    Please let me know if you find anything on the play position.

    Scott

  • #60604
    Profile photo of Ron
    Ron
    Participant

    Ideally you don't want to be locked in a closed timing loop. If the comobject does not provide a suitable event when the songs change or start, then add a timer to your form and use those events to update the current song info. That way the rest of your form remains responsive.

  • #60610
    Profile photo of Dan Potter
    Dan Potter
    Participant

    I'll get it eventually, it usually comes to me just as I start to go to sleep:D I tried it with and without the temp playlist to no avail.

    Another issue with compiling the albums list is grouping by album/artist generates duplicate for albums that are compilations of artists.

  • #60613
    Profile photo of Scott Windmiller
    Scott Windmiller
    Participant

    Yeah, ideally what I was after was to select a playlist and play that playlist. I also wanted to list the tracks in that playlist (which I can) then select a certain track from that playlist to play. This all works but like you said, the play position is screwing me up.
    I select the playlist and it starts playing song 1, then I select song 5 and it starts playing. Once 5 is over, song 2 starts playing. This is an annoying problem, I would want song 6 to play.

    I really hope you figure it out 🙂

    Thanks for all the help!!

  • #60643
    Profile photo of Dan Potter
    Dan Potter
    Participant

    So..if you uncheck all the songs in the library, itunes will not automatically play the next song. In the timertick event we need to put an if for playerstate -eq 0..add current song index + 1 and execute the play method on that song.

    Another setback, you can't create a playlist for music that hasn't been downloaded.

You must be logged in to reply to this topic.