diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py
index 0aac8dd16..189718d47 100644
--- a/openlp/core/lib/__init__.py
+++ b/openlp/core/lib/__init__.py
@@ -137,7 +137,7 @@ from settingstab import SettingsTab
from mediamanageritem import MediaManagerItem
from xmlrootclass import XmlRootClass
from serviceitem import ServiceItem
-from serviceitem import ServiceType
+from serviceitem import ServiceItemType
from serviceitem import ServiceItem
from toolbar import OpenLPToolbar
from dockwidget import OpenLPDockWidget
diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py
index 14606a948..325eb72d3 100644
--- a/openlp/core/lib/mediamanageritem.py
+++ b/openlp/core/lib/mediamanageritem.py
@@ -388,7 +388,8 @@ class MediaManagerItem(QtGui.QWidget):
if self.ServiceItemIconName is not None:
service_item.addIcon(self.ServiceItemIconName)
else:
- service_item.addIcon(self.icon)
+ service_item.addIcon(
+ u':/media/media_' + self.PluginNameShort.lower() + u'.png')
if self.generateSlideData(service_item):
self.ListView.clearSelection()
return service_item
diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py
index b9c82c798..7fab33ea3 100644
--- a/openlp/core/lib/serviceitem.py
+++ b/openlp/core/lib/serviceitem.py
@@ -30,13 +30,14 @@ from PyQt4 import QtGui
from openlp.core.lib import buildIcon
-class ServiceType(object):
+class ServiceItemType(object):
"""
Defines the type of service item
"""
Text = 1
Image = 2
Command = 3
+ Video = 4
class ServiceItem(object):
"""
@@ -91,7 +92,7 @@ class ServiceItem(object):
"""
log.debug(u'Render called')
self.frames = []
- if self.service_item_type == ServiceType.Text:
+ if self.service_item_type == ServiceItemType.Text:
log.debug(u'Formatting slides')
if self.theme is None:
self.RenderManager.set_override_theme(None)
@@ -109,9 +110,9 @@ class ServiceItem(object):
self.frames.append({u'title': title, u'text': lines,
u'image': frame})
log.info(u'Formatting took %4s' % (time.time() - before))
- elif self.service_item_type == ServiceType.Command:
+ elif self.service_item_type == ServiceItemType.Command:
self.frames = self.service_frames
- elif self.service_item_type == ServiceType.Image:
+ elif self.service_item_type == ServiceItemType.Image:
for slide in self.service_frames:
slide[u'image'] = \
self.RenderManager.resize_image(slide[u'image'])
@@ -148,10 +149,16 @@ class ServiceItem(object):
``image``
The actual image file name.
"""
- self.service_item_type = ServiceType.Image
+ self.service_item_type = ServiceItemType.Image
self.service_item_path = path
self.service_frames.append(
- {u'title': frame_title, u'text':None, u'image': image})
+ {u'title': frame_title, u'text': None, u'image': image})
+
+ def add_from_media(self, path, frame_title, image):
+ self.service_item_type = ServiceItemType.Video
+ self.service_item_path = path
+ self.service_frames.append(
+ {u'title': frame_title, u'text': None, u'image': image})
def add_from_text(self, frame_title, raw_slide):
"""
@@ -163,7 +170,7 @@ class ServiceItem(object):
``raw_slide``
The raw text of the slide.
"""
- self.service_item_type = ServiceType.Text
+ self.service_item_type = ServiceItemType.Text
frame_title = frame_title.split(u'\n')[0]
self.service_frames.append(
{u'title': frame_title, u'raw_slide': raw_slide})
@@ -178,7 +185,7 @@ class ServiceItem(object):
``command``
The command of/for the slide.
"""
- self.service_item_type = ServiceType.Command
+ self.service_item_type = ServiceItemType.Command
self.service_item_path = path
self.service_frames.append(
{u'title': frame_title, u'command': None, u'text':None, u'image': image})
@@ -199,13 +206,16 @@ class ServiceItem(object):
u'audit':self.audit
}
service_data = []
- if self.service_item_type == ServiceType.Text:
+ if self.service_item_type == ServiceItemType.Text:
for slide in self.service_frames:
service_data.append(slide)
- elif self.service_item_type == ServiceType.Image:
+ elif self.service_item_type == ServiceItemType.Image:
for slide in self.service_frames:
service_data.append(slide[u'title'])
- elif self.service_item_type == ServiceType.Command:
+ elif self.service_item_type == ServiceItemType.Command:
+ for slide in self.service_frames:
+ service_data.append(slide[u'title'])
+ elif self.service_item_type == ServiceItemType.Video:
for slide in self.service_frames:
service_data.append(slide[u'title'])
return {u'header': service_header, u'data': service_data}
@@ -230,15 +240,17 @@ class ServiceItem(object):
self.addIcon(header[u'icon'])
self.raw_footer = header[u'footer']
self.audit = header[u'audit']
- if self.service_item_type == ServiceType.Text:
+ if self.service_item_type == ServiceItemType.Text:
for slide in serviceitem[u'serviceitem'][u'data']:
self.service_frames.append(slide)
- elif self.service_item_type == ServiceType.Image:
+ elif self.service_item_type == ServiceItemType.Image:
for text_image in serviceitem[u'serviceitem'][u'data']:
filename = os.path.join(path, text_image)
real_image = QtGui.QImage(unicode(filename))
self.add_from_image(path, text_image, real_image)
- elif self.service_item_type == ServiceType.Command:
+ elif self.service_item_type == ServiceItemType.Command:
for text_image in serviceitem[u'serviceitem'][u'data']:
filename = os.path.join(path, text_image)
self.add_from_command(path, text_image)
+ elif self.service_item_type == ServiceItemType.Video:
+ pass
diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py
index 6f3bf910d..e59f399b4 100644
--- a/openlp/core/ui/maindisplay.py
+++ b/openlp/core/ui/maindisplay.py
@@ -23,7 +23,10 @@
###############################################################################
import logging
+import os
+
from PyQt4 import QtCore, QtGui
+from PyQt4.phonon import Phonon
from openlp.core.lib import Receiver, str_to_bool
@@ -85,15 +88,23 @@ class MainDisplay(DisplayLabel):
self.layout.setSpacing(0)
self.layout.setMargin(0)
self.layout.setObjectName(u'layout')
+ self.mediaObject = Phonon.MediaObject(self)
+ self.video = Phonon.VideoWidget()
+ self.audio = Phonon.AudioOutput(Phonon.VideoCategory, self.mediaObject)
+ self.video.setFullScreen(True)
+ Phonon.createPath(self.mediaObject, self.video)
+ Phonon.createPath(self.mediaObject, self.audio)
+ self.layout.insertWidget(0, self.video)
self.display = QtGui.QLabel(self)
self.display.setScaledContents(True)
- self.layout.addWidget(self.display)
+ self.layout.insertWidget(0, self.display)
self.displayBlank = False
self.blankFrame = None
self.frame = None
self.alertactive = False
self.alertTab = None
self.timer_id = 0
+ self.firstTime = True
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'live_slide_blank'), self.blankDisplay)
QtCore.QObject.connect(Receiver.get_receiver(),
@@ -102,6 +113,17 @@ class MainDisplay(DisplayLabel):
QtCore.SIGNAL(u'presentations_start'), self.hideDisplay)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'presentations_stop'), self.showDisplay)
+ QtCore.QObject.connect(self.mediaObject,
+ QtCore.SIGNAL(u'finished()'), self.onMediaFinish)
+ QtCore.QObject.connect(Receiver.get_receiver(),
+ QtCore.SIGNAL(u'media_start'), self.onMediaQueue)
+ QtCore.QObject.connect(Receiver.get_receiver(),
+ QtCore.SIGNAL(u'media_play'), self.onMediaPlay)
+ QtCore.QObject.connect(Receiver.get_receiver(),
+ QtCore.SIGNAL(u'media_pause'), self.onMediaPaws)
+ QtCore.QObject.connect(Receiver.get_receiver(),
+ QtCore.SIGNAL(u'media_stop'), self.onMediaFinish)
+
def setup(self, screenNumber):
"""
@@ -221,3 +243,28 @@ class MainDisplay(DisplayLabel):
self.display.setPixmap(QtGui.QPixmap.fromImage(self.frame))
self.killTimer(self.timer_id)
self.timer_id = 0
+
+ def onMediaQueue(self, message):
+ self.display.close()
+ file = os.path.join(message[1], message[2])
+ if self.firstTime:
+ self.mediaObject.setCurrentSource(Phonon.MediaSource(file))
+ self.firstTime = False
+ else:
+ self.mediaObject.enqueue(Phonon.MediaSource(file))
+ self.onMediaPlay()
+
+ def onMediaPlay(self):
+ self.display.hide()
+ self.mediaObject.play()
+ self.setVisible(True)
+
+ def onMediaPaws(self):
+ self.mediaObject.pause()
+
+ def onMediaFinish(self):
+ self.setVisible(False)
+ self.mediaObject.stop()
+ self.mediaObject.clearQueue()
+ self.video.close()
+ self.display.show()
diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py
index 278896e9e..68dc2bd62 100644
--- a/openlp/core/ui/servicemanager.py
+++ b/openlp/core/ui/servicemanager.py
@@ -30,8 +30,8 @@ import zipfile
from PyQt4 import QtCore, QtGui
from openlp.core.lib import PluginConfig, OpenLPToolbar, ServiceItem, \
- ServiceType, contextMenuAction, contextMenuSeparator, Receiver, \
- contextMenu, str_to_bool
+ ServiceItemType, contextMenuAction, contextMenuSeparator, contextMenu, \
+ Receiver, contextMenu, str_to_bool
class ServiceManagerList(QtGui.QTreeWidget):
@@ -443,8 +443,8 @@ class ServiceManager(QtGui.QWidget):
for item in self.serviceItems:
service.append(
{u'serviceitem':item[u'data'].get_service_repr()})
- if item[u'data'].service_item_type == ServiceType.Image or \
- item[u'data'].service_item_type == ServiceType.Command:
+ if item[u'data'].service_item_type == ServiceItemType.Image or \
+ item[u'data'].service_item_type == ServiceItemType.Command:
for frame in item[u'data'].frames:
path_from = unicode(os.path.join(
item[u'data'].service_item_path, frame[u'title']))
diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py
index d00c045d4..557b468aa 100644
--- a/openlp/core/ui/slidecontroller.py
+++ b/openlp/core/ui/slidecontroller.py
@@ -26,7 +26,8 @@ import logging
import time
from PyQt4 import QtCore, QtGui
-from openlp.core.lib import OpenLPToolbar, Receiver, ServiceType, str_to_bool, PluginConfig
+from openlp.core.lib import OpenLPToolbar, Receiver, ServiceItemType, \
+ str_to_bool, PluginConfig
class SlideList(QtGui.QTableWidget):
"""
@@ -79,6 +80,11 @@ class SlideController(QtGui.QWidget):
u'Loop Separator',
u'Image SpinBox'
]
+ self.media_list = [
+ u'Media Start',
+ u'Media Stop',
+ u'Media Pause'
+ ]
self.song_list = [
u'Edit Song',
]
@@ -171,6 +177,16 @@ class SlideController(QtGui.QWidget):
u'Image SpinBox', self.DelaySpinBox)
self.DelaySpinBox.setSuffix(self.trUtf8(u's'))
self.DelaySpinBox.setToolTip(self.trUtf8(u'Delay between slides in seconds'))
+ self.Toolbar.addToolbarButton(
+ u'Media Start', u':/slides/media_playback_start.png',
+ self.trUtf8(u'Start playing media'), self.onMediaPlay)
+ self.Toolbar.addToolbarButton(
+ u'Media Pause', u':/slides/media_playback_pause.png',
+ self.trUtf8(u'Start playing media'), self.onMediaPause)
+ self.Toolbar.addToolbarButton(
+ u'Media Stop', u':/slides/media_playback_stop.png',
+ self.trUtf8(u'Start playing media'), self.onMediaStop)
+
self.ControllerLayout.addWidget(self.Toolbar)
# Build the Song Toolbar
if isLive:
@@ -231,6 +247,7 @@ class SlideController(QtGui.QWidget):
Receiver().send_message(u'request_spin_delay')
if isLive:
self.Toolbar.makeWidgetsInvisible(self.image_list)
+ self.Toolbar.makeWidgetsInvisible(self.media_list)
else:
self.Toolbar.makeWidgetsInvisible(self.song_list)
QtCore.QObject.connect(Receiver.get_receiver(),
@@ -278,7 +295,8 @@ class SlideController(QtGui.QWidget):
"""
self.Songbar.setVisible(False)
self.Toolbar.makeWidgetsInvisible(self.image_list)
- if item.service_item_type == ServiceType.Text:
+ self.Toolbar.makeWidgetsInvisible(self.media_list)
+ if item.service_item_type == ServiceItemType.Text:
self.Toolbar.makeWidgetsInvisible(self.image_list)
if item.name == u'Songs' and \
str_to_bool(self.songsconfig.get_config(u'display songbar', True)):
@@ -293,10 +311,13 @@ class SlideController(QtGui.QWidget):
#More than 20 verses hard luck
pass
self.Songbar.setVisible(True)
- elif item.service_item_type == ServiceType.Image:
+ elif item.service_item_type == ServiceItemType.Image:
#Not sensible to allow loops with 1 frame
if len(item.frames) > 1:
self.Toolbar.makeWidgetsVisible(self.image_list)
+ elif item.service_item_type == ServiceItemType.Command and \
+ item.name == u'Media':
+ self.Toolbar.makeWidgetsVisible(self.media_list)
def enablePreviewToolBar(self, item):
"""
@@ -316,14 +337,14 @@ class SlideController(QtGui.QWidget):
log.debug(u'addServiceItem')
#If old item was a command tell it to stop
if self.commandItem is not None and \
- self.commandItem.service_item_type == ServiceType.Command:
+ self.commandItem.service_item_type == ServiceItemType.Command:
Receiver().send_message(u'%s_stop'% self.commandItem.name.lower())
self.commandItem = item
before = time.time()
item.render()
log.info(u'Rendering took %4s' % (time.time() - before))
self.enableToolBar(item)
- if item.service_item_type == ServiceType.Command:
+ if item.service_item_type == ServiceItemType.Command:
Receiver().send_message(u'%s_start' % item.name.lower(), \
[item.shortname, item.service_item_path,
item.service_frames[0][u'title']])
@@ -350,11 +371,11 @@ class SlideController(QtGui.QWidget):
log.debug(u'addServiceManagerItem')
#If old item was a command tell it to stop
if self.commandItem is not None and \
- self.commandItem.service_item_type == ServiceType.Command:
+ self.commandItem.service_item_type == ServiceItemType.Command:
Receiver().send_message(u'%s_stop'% self.commandItem.name.lower())
self.commandItem = item
self.enableToolBar(item)
- if item.service_item_type == ServiceType.Command:
+ if item.service_item_type == ServiceItemType.Command:
Receiver().send_message(u'%s_start' % item.name.lower(), \
[item.shortname, item.service_item_path,
item.service_frames[0][u'title'], slideno])
@@ -413,7 +434,7 @@ class SlideController(QtGui.QWidget):
Go to the first slide.
"""
if self.commandItem is not None and \
- self.commandItem.service_item_type == ServiceType.Command:
+ self.commandItem.service_item_type == ServiceItemType.Command:
Receiver().send_message(u'%s_first'% self.commandItem.name.lower())
QtCore.QTimer.singleShot(0.5, self.grabMainDisplay)
else:
@@ -425,7 +446,7 @@ class SlideController(QtGui.QWidget):
Blank the screen.
"""
if self.commandItem is not None and \
- self.commandItem.service_item_type == ServiceType.Command:
+ self.commandItem.service_item_type == ServiceItemType.Command:
if blanked:
Receiver().send_message(u'%s_blank'% self.commandItem.name.lower())
else:
@@ -441,9 +462,9 @@ class SlideController(QtGui.QWidget):
row = self.PreviewListWidget.currentRow()
self.row = 0
if row > -1 and row < self.PreviewListWidget.rowCount():
- if self.commandItem.service_item_type == ServiceType.Command:
+ if self.commandItem.service_item_type == ServiceItemType.Command:
Receiver().send_message(u'%s_slide'% self.commandItem.name.lower(), [row])
- if isLive:
+ if self.isLive:
QtCore.QTimer.singleShot(0.5, self.grabMainDisplay)
else:
frame = self.serviceitem.frames[row][u'image']
@@ -479,7 +500,7 @@ class SlideController(QtGui.QWidget):
Go to the next slide.
"""
if self.commandItem is not None and \
- self.commandItem.service_item_type == ServiceType.Command:
+ self.commandItem.service_item_type == ServiceItemType.Command:
Receiver().send_message(u'%s_next'% self.commandItem.name.lower())
QtCore.QTimer.singleShot(0.5, self.grabMainDisplay)
else:
@@ -494,7 +515,7 @@ class SlideController(QtGui.QWidget):
Go to the previous slide.
"""
if self.commandItem is not None and \
- self.commandItem.service_item_type == ServiceType.Command:
+ self.commandItem.service_item_type == ServiceItemType.Command:
Receiver().send_message(
u'%s_previous'% self.commandItem.name.lower())
QtCore.QTimer.singleShot(0.5, self.grabMainDisplay)
@@ -510,7 +531,7 @@ class SlideController(QtGui.QWidget):
Go to the last slide.
"""
if self.commandItem is not None and \
- self.commandItem.service_item_type == ServiceType.Command:
+ self.commandItem.service_item_type == ServiceItemType.Command:
Receiver().send_message(u'%s_last'% self.commandItem.name.lower())
QtCore.QTimer.singleShot(0.5, self.grabMainDisplay)
else:
@@ -550,3 +571,12 @@ class SlideController(QtGui.QWidget):
if row > -1 and row < self.PreviewListWidget.rowCount():
self.parent.LiveController.addServiceManagerItem(
self.commandItem, row)
+
+ def onMediaPause(self):
+ Receiver().send_message(u'%s_pause'% self.commandItem.name.lower())
+
+ def onMediaPlay(self):
+ Receiver().send_message(u'%s_play'% self.commandItem.name.lower())
+
+ def onMediaStop(self):
+ Receiver().send_message(u'%s_stop'% self.commandItem.name.lower())
diff --git a/openlp/plugins/media/lib/mediaitem.py b/openlp/plugins/media/lib/mediaitem.py
index 544e5d767..2a98f78b7 100644
--- a/openlp/plugins/media/lib/mediaitem.py
+++ b/openlp/plugins/media/lib/mediaitem.py
@@ -45,14 +45,15 @@ class MediaMediaItem(MediaManagerItem):
def __init__(self, parent, icon, title):
self.PluginNameShort = u'Media'
self.IconPath = u'images/image'
+ self.ConfigSection = u'media'
self.ConfigSection = title
- self.OnNewFileMasks = \
- u'Videos (*.avi *.mpeg *.mpg *.mp4);;Audio (*.ogg *.mp3 *.wma);;All files (*)'
# this next is a class, not an instance of a class - it will
# be instanced by the base MediaManagerItem
self.ListViewWithDnD_class = MediaListView
+ self.ServiceItemIconName = u':/media/media_video.png'
self.PreviewFunction = self.video_get_preview
MediaManagerItem.__init__(self, parent, icon, title)
+ self.MainDisplay = self.parent.live_controller.parent.mainDisplay
def initPluginNameVisible(self):
self.PluginNameVisible = self.trUtf8(u'Media')
@@ -60,40 +61,61 @@ class MediaMediaItem(MediaManagerItem):
def retranslateUi(self):
self.OnNewPrompt = self.trUtf8(u'Select Media')
+ def reTranslateUI(self):
+ self.OnNewPrompt = self.trUtf8(u'Select Media')
+ self.OnNewFileMasks = self.trUtf8(u'Videos (*.avi *.mpeg *.mpg'
+ '*.mp4);;Audio (*.ogg *.mp3 *.wma);;All files (*)')
+
def requiredIcons(self):
MediaManagerItem.requiredIcons(self)
self.hasFileIcon = True
self.hasNewIcon = False
self.hasEditIcon = False
- def video_get_preview(self, filename):
+ def video_get_preview(self):
# For now cross platform is an icon. Phonon does not support
# individual frame access (yet?) and GStreamer is not available
# on Windows
return QtGui.QPixmap(u':/media/media_video.png').toImage()
def generateSlideData(self, service_item):
- indexes = self.ListView.selectedIndexes()
- if len(indexes) > 1:
+ items = self.ListView.selectedIndexes()
+ if len(items) > 1:
return False
- service_item.title = u'Media'
- for index in indexes:
- filename = self.ListData.getFilename(index)
- frame = QtGui.QImage(unicode(filename))
+ service_item.title = self.trUtf8(u'Media')
+ for item in items:
+ bitem = self.ListView.item(item.row())
+ filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString())
+ frame = u':/media/media_video.png'
(path, name) = os.path.split(filename)
- service_item.add_from_image(path, name, frame)
+ #service_item.add_from_image(path, name, frame)
+ print path
+ print name
+ service_item.add_from_command(path, name, frame)
return True
- def onPreviewClick(self):
- log.debug(u'Media Preview Button pressed')
- items = self.ListView.selectedIndexes()
- for item in items:
- text = self.ListData.getValue(item)
- print text
-
- def onMediaLiveClick(self):
- log.debug(u'Media Live Button pressed')
- pass
+# def onPreviewClick(self):
+# log.debug(u'Media Preview Button pressed')
+# items = self.ListView.selectedIndexes()
+# for item in items:
+# baseItem = self.ListView.item(item.row())
+# itemText = unicode(baseItem.data(QtCore.Qt.UserRole).toString())
+# print itemText
+#
+# def onLiveClick(self):
+# log.debug(u'Media Live Button pressed')
+# items = self.ListView.selectedIndexes()
+# if len(items) > 0:
+# firstPass = True
+# for item in items:
+# baseItem = self.ListView.item(item.row())
+# filename = unicode(baseItem.data(QtCore.Qt.UserRole).toString())
+# if firstPass:
+# self.MainDisplay.queueMedia(filename, firstPass)
+# firstPass = False
+# else:
+# self.MainDisplay.queueMedia(filename, firstPass)
+# self.MainDisplay.playMedia()
def initialise(self):
self.ListView.setSelectionMode(
@@ -113,7 +135,7 @@ class MediaMediaItem(MediaManagerItem):
for file in list:
(path, filename) = os.path.split(unicode(file))
item_name = QtGui.QListWidgetItem(filename)
- img = self.video_get_preview(file)
+ img = self.video_get_preview()
item_name.setIcon(buildIcon(img))
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file))
self.ListView.addItem(item_name)
diff --git a/openlp/plugins/presentations/lib/mediaitem.py b/openlp/plugins/presentations/lib/mediaitem.py
index 550c15b60..b49b37627 100644
--- a/openlp/plugins/presentations/lib/mediaitem.py
+++ b/openlp/plugins/presentations/lib/mediaitem.py
@@ -51,7 +51,6 @@ class PresentationMediaItem(MediaManagerItem):
self.PluginNameShort = u'Presentation'
self.ConfigSection = title
self.IconPath = u'presentations/presentation'
- self.OnNewFileMasks = u'Presentations (*.ppt *.pps *.odp)'
# this next is a class, not an instance of a class - it will
# be instanced by the base MediaManagerItem
self.ListViewWithDnD_class = PresentationListView
@@ -64,6 +63,10 @@ class PresentationMediaItem(MediaManagerItem):
def retranslateUi(self):
self.OnNewPrompt = self.trUtf8(u'Select Presentation(s)')
+ def reTranslateUI(self):
+ self.OnNewPrompt = self.trUtf8(u'Select Presentation(s)')
+ self.OnNewFileMasks = self.trUtf8(u'Presentations (*.ppt *.pps *.odp)')
+
def requiredIcons(self):
MediaManagerItem.requiredIcons(self)
self.hasFileIcon = True
diff --git a/resources/images/media_playback_pause.png b/resources/images/media_playback_pause.png
new file mode 100644
index 000000000..a9b3113fb
Binary files /dev/null and b/resources/images/media_playback_pause.png differ
diff --git a/resources/images/media_playback_start.png b/resources/images/media_playback_start.png
new file mode 100644
index 000000000..80ff3a1d5
Binary files /dev/null and b/resources/images/media_playback_start.png differ
diff --git a/resources/images/media_playback_stop.png b/resources/images/media_playback_stop.png
new file mode 100644
index 000000000..180280e8b
Binary files /dev/null and b/resources/images/media_playback_stop.png differ
diff --git a/resources/images/openlp-2.qrc b/resources/images/openlp-2.qrc
index 83c88c3e5..f7e6f095f 100644
--- a/resources/images/openlp-2.qrc
+++ b/resources/images/openlp-2.qrc
@@ -27,6 +27,9 @@
slide_last.png
slide_next.png
slide_previous.png
+ media_playback_start.png
+ media_playback_stop.png
+ media_playback_pause.png
openlp-logo-16x16.png
diff --git a/version.txt b/version.txt
index bb9e5eaca..02bb4725f 100644
--- a/version.txt
+++ b/version.txt
@@ -1 +1 @@
-1.9.0-641
+1.9.0-646