How to: Make a Screen Saver that Plays Movie Trailers? (Easter Egg Included in Executable Version)
How to make a screen saver that plays movie trailers
Introduction
I decided to build a screensaver that plays movie trailers. The purpose was to learn about how screensavers worked and build a random movie trailer screensaver. The code pulls the trailers from the trailer API at http://api.traileraddict.com. I chose trailer addict because the XML for retrieving movie trailers was simple. In addition, I have an Easter egg in my original code which I am leaving out of this article to help make it brief and easily manageable. However, the executable does include an Easter egg, so feel free to try it out.
Making/Coding Screen Saver Form
For this article, I have named the screensaver form: frmScreenSaver
. The following properties are important to set and need to be set for frmScreenSaver
:
FormBorderStyle
- NoneWindowsState
- Maximized (after you finishing debugging the screensaver)MinimizeBox
-False
MaximizeBox
-False
ShowInTaskbar
-False
(can set totrue
during debugging)
In addition, the Shockwave Flash component needs to be added to frmScreenSaver
(can be added to the toolbox via COM component tab in Choose Toolbox Items Dialog) and resized to fit onto the whole form. frmScreenSaver
is shown in Dialog 1 below with the Shockwave Flash Object added.
Dialog 1 - frmScreenSaver with ShockWave Flash Object
In Figure 1, the screensaver form code below first loads the option information from an XML file (will show code for saving/loading XML file later below). Next, it proceeds to adding a timer interval of 500 ms to the timer on the form so that the first trailer will load fast. The formsize
variable below was used to make the trailer automatically size to fullscreen
after debugging of the application was finished. Then, the timer is started and the loaded options are checked for the timer interval. If no interval is selected, the default is 60 secs (60000 ms). Third, a random movie trailer is pulled from a collection of 6 from the category set in the options form and the trailer is supposed to start playing automatically (I was having trouble playing the trailer automatically with trailer addicts API). Finally, the key press events are added to allow an escape key to be pressed to escape the screensaver (oddly, mouse capture events do not work with the flash ActiveX control or I might have used them improperly).
Public Class frmScreenSaver
Private FirstTrailer As Boolean
Private Sub frmScreenSaver_Load(sender As Object, e As EventArgs) Handles Me.Load
myoptions.LoadOptions()
'have the first trailers timer be low so it will start playing quicker
TrailerRotateTimer.Interval = 500
TrailerRotateTimer.Stop()
Dim formsize As Size
formsize.Height = Me.Size.Height
formsize.Width = Me.Size.Width
Video.Size = formsize
Video.AllowFullScreen = True
Video.Visible = True
TrailerRotateTimer.Start()
End Sub
Private Sub TrailerRotateTimer_Tick(sender As Object, e As EventArgs) _
Handles TrailerRotateTimer.Tick
If FirstTrailer = False Then
Select Case myoptions.TrailerPlayTime
Case Is = 60
TrailerRotateTimer.Interval = 60000
FirstTrailer = True
Case Is = 90
TrailerRotateTimer.Interval = 90000
FirstTrailer = True
Case Is = 120
TrailerRotateTimer.Interval = 120000
FirstTrailer = True
Case Else
TrailerRotateTimer.Interval = 60000
FirstTrailer = True
End Select
End If
Dim randnum As New Random()
Dim firstvideo As String = myoptions.TrailerUrlCollection.Item(randnum.Next(0, 5))
' Video.Movie = firstvideo
Video.Stop()
Video.LoadMovie(0, firstvideo)
If Video.IsPlaying = False Then
' Video.Playing = True
Video.Play()
Video.Playing = True
Video.Loop = False
End If
End Sub
Private Sub frmScreenSaver_KeyPress(sender As Object, e As KeyPressEventArgs) Handles Me.KeyPress
If e.KeyChar <> "" Then
Application.Exit()
End If
End Sub
Private Sub Video_PreviewKeyDown(sender As Object, e As PreviewKeyDownEventArgs) _
Handles Video.PreviewKeyDown
If e.KeyCode = Keys.Escape Then
Application.Exit()
End If
End Sub
End Class
Making/Coding frmOptions
frmOptions
was easy to code and only had five controls: two label
s, a combobox
named cboGenre
, another combobox
named cboPlayTime
, and a button
named BtnSave
. Dialog 2 provides a preview of what frmOptions
looks like.
Dialog 2 - frmOptions
Figure 2 shows how the load code loads the options and selects the option already set previously in the XML file. In addition, it shows the code for the BtnSave
click event which calls RetrieveVideos
which retrieves 6 videos from the API service, retrieves the pause time in-between screensavers, and saves the information to an XML file.
Public Class frmOptions
Private Sub frmOptions_Load(sender As Object, e As EventArgs) Handles MyBase.Load
myoptions.LoadOptions()
If myoptions.VideoGenreSelection <> "" Then
cboGenre.SelectedIndex = cboGenre.Items.IndexOf(myoptions.VideoGenreSelection)
Else
cboGenre.SelectedIndex = 0
End If
End Sub
Private Sub BtnSave_Click(sender As Object, e As EventArgs) Handles BtnSave.Click
myoptions.IsTransparent = False
If cboGenre.SelectedIndex > -1 Then
myoptions.TrailerUrlCollection = ProgramServices.RetrieveVideos_
(cboGenre.Items.Item(cboGenre.SelectedIndex))
myoptions.VideoGenreSelection = cboGenre.Items.Item(cboGenre.SelectedIndex)
If IsNumeric(cboPlayTime.Text) Then
myoptions.TrailerPlayTime = CInt(cboPlayTime.Text)
End If
myoptions.SaveOptions()
Me.Close()
Else
MsgBox("need to have a genre selected!")
End If
End Sub
End Class
Retrieving Videos from TrailerAddict
Now, we actually show how the videos are retrieved from Trailer Addicts movie trailer service. I created a class called ProgramServices
and a Shared Function called RetrieveVideos
to retrieve the trailers from trailer addict. This line:
Dim url As String = "http://api.traileraddict.com/?actor=" + genre.ToLower + "&count=6"
retrieves the XML that contains the 6 different trailer urls. To try out different options, go to http://www.traileraddict.com and play with it (look for the gears icon that has a tool-tip with API in it to see the url you can use to get your result). I used actor because it allows me to separate out the trailers by genre. The rest of the code in Figure 3 retrieves the trailer id of each trailer which I add to a variable called templst
and return to be saved in the XML options file. Note: This section of code with the address automatically returns the SWF player for each trailer: http://v.traileraddict.com/emd/
Imports System.Net
Imports System.Text
Imports System.IO
Public Class ProgramServices
Public Shared Function RetrieveVideos(genre As String) As List(Of String)
Dim templst As New List(Of String)
'retrieve top 4 videos and add them to the list
Dim url As String = "http://api.traileraddict.com/?actor=" + _
genre.ToLower + "&count=6"
Dim req As HttpWebRequest = WebRequest.Create(url)
Dim resp As HttpWebResponse = req.GetResponse()
Dim enc As Encoding = System.Text.Encoding.GetEncoding(1252)
Dim loResponseStream As StreamReader =
New StreamReader(resp.GetResponseStream(), enc)
Dim Response As String = loResponseStream.ReadToEnd()
Dim xmlfile As XDocument = XDocument.Parse(Response)
Dim videos As IEnumerable(Of XElement) = From t In xmlfile.Descendants("trailers") Select t
For Each video As XElement In videos
For Each trailer As XElement In video.Elements("trailer")
templst.Add("http://v.traileraddict.com/emd/"+_
trailer.Element("trailer_id").Value+"?id=" + _
trailer.Element("trailer_id").Value)
Next
Next
loResponseStream.Close()
resp.Close()
Return templst
End Function
End Class
Saving/Opening from/to Options XML file
Saving to the options XML file is easy. I reference some code from this article for saving to the XML file but changed some code to make it applicable for my scenario: http://www.devasp.net/net/articles/display/566.html. Figure 4 shows the whole code for saving to the XML file. I would go into explaining the whole thing but looking at it, most of it is self explanatory. However, to help people better understand the code, there are some important things to mention:
My settings file is named settings.opt and will be created/loaded from wherever the screensaver is placed, m_VideoTrailerUrl
is the list of movie trailer urls that are retrieved from trailer addicts API (in string
format), and m_GSelection
is the genre selection (defaults to Sci-fi), and m_TrailerPlayTime
is the time each trailer has to play (defaults to 60 seconds).
Option Strict On
Imports System.Xml.Serialization
Imports System.Xml
Imports System.IO
<serializable> Public Class Options
Private m_VideoTrailerUrl As List(Of String)
Private m_IsTransparent As Boolean = True
Private m_GSelection As String = "Sci-fi"
Private m_TrailerPlayTime As Integer = 60
' Set the OptionsPath to the current location with a fixed file name.
Private OptionsPath As String = Application.StartupPath & "\settings.opt"
' This property returns whether the screen saver should use transparency
' when drawing the shapes to the screen.
Public Property IsTransparent() As Boolean
Get
Return m_IsTransparent
End Get
Set(ByVal Value As Boolean)
m_IsTransparent = Value
End Set
End Property
' This property returns what genre video to retrieve from the trailer service.
Public Property VideoGenreSelection() As String
Get
Return m_GSelection
End Get
Set(value As String)
m_GSelection = value
End Set
End Property
Public Property TrailerPlayTime As Integer
Get
Return m_TrailerPlayTime
End Get
Set(value As Integer)
m_TrailerPlayTime = value
End Set
End Property
' This property returns what speed the screen saver should use
' when drawing to the screen.
Public Property TrailerUrlCollection As List(Of String)
Get
Return m_VideoTrailerUrl
End Get
Set(ByVal Value As List(Of String))
m_VideoTrailerUrl = Value
End Set
End Property
' --- Class Methods ---
' This function returns 'true' if the options file exists, 'false' otherwise.
Public Function IsOptionFileExisting() As Boolean
Dim myIO As New System.IO.FileInfo(OptionsPath)
Return myIO.Exists()
End Function
' This function loads the user defined options. First, it checks to see
' if an options file exists. If it does, the options are loaded from it.
' If the file doesn't exist, one is created with the defaults.
Public Sub LoadOptions()
Dim myOptions As New Options ' An Options object to use
' Check to see if an Option file exists, if so, load it! Else
' create one.
If myOptions.IsOptionFileExisting() Then
' Load the options
' Create an XmlSerializer to use for retrieving options values
Dim mySerializer As New XmlSerializer(GetType(Options))
' Create a StreamReader to point to the options file
Dim myTextReader As New StreamReader(OptionsPath)
' Create an XmlTextReader to actually read the options.
Dim myXmlReader As New Xml.XmlTextReader(myTextReader)
' First verify that the file can be deserialized into an Option
' object format.
If mySerializer.CanDeserialize(myXmlReader) Then
' Deserialize the object
myOptions = CType(mySerializer.Deserialize(myXmlReader), Options)
Else
' Save a new Options file
myOptions.SaveOptions()
End If
' Close the IO objects we've used.
myXmlReader.Close()
myTextReader.Close()
' Set the properties for this Options object to those retrieved
' from the file (or else use the defaults from the temporary
' Options object, if the file could not be deserialized).
Me.m_GSelection = myOptions.m_GSelection
Me.m_IsTransparent = myOptions.IsTransparent
Me.m_VideoTrailerUrl = myOptions.m_VideoTrailerUrl
End If
End Sub
' This function saves the user defined options to disk.
Public Sub SaveOptions()
' Create a stream writer to overwrite any files currently there, so that
' the fresh options can be saved.
Dim myWriter As New System.IO.StreamWriter(OptionsPath)
' Create an XML Serializer to serialize the object
Dim myXmlSerializer As New XmlSerializer(Me.GetType())
' Serialize the current Options object (Me) to disk.
myXmlSerializer.Serialize(myWriter, Me)
' Close the writer.
myWriter.Close()
End Sub
End Class
Other Related Articles
- Article on making Screensavers in VB.NET: http://www.devasp.net/net/articles/display/566.html