Implemented video playback for questions
This commit is contained in:
parent
d7a2d8c56a
commit
09466d83a8
|
@ -40,6 +40,7 @@ five questions. A question can have the following keys:
|
|||
- Answer (to remind you of the answer, not used in the program)
|
||||
- Type (type of question)
|
||||
- Double-Jeopardy (if the question is a Double-Jeopardy, default false)
|
||||
- Audio (for videos, if the video should have audio or not, default false)
|
||||
|
||||
Four *Types* of question are supported:
|
||||
|
||||
|
@ -48,6 +49,7 @@ Four *Types* of question are supported:
|
|||
four spaces
|
||||
- Image: The Question key is a path to an image, which is displayed on screen
|
||||
- Music: The Question key is a path to a music file, which is played
|
||||
- Video: The Question key is a path to a video file, which is played
|
||||
|
||||
|
||||
Gamestate
|
||||
|
|
14
question.py
14
question.py
|
@ -10,8 +10,8 @@ class QuestionException(Exception):
|
|||
class Questions(object):
|
||||
""" Object holding all the questions """
|
||||
|
||||
QUESTION_TYPES = ["Text", "Image", "Music", "Code"]
|
||||
QUESTION_KEYS = ["Name", "Question", "Answer", "Type", "Double-Jeopardy"]
|
||||
QUESTION_TYPES = ["Text", "Image", "Music", "Code", "Video"]
|
||||
QUESTION_KEYS = ["Name", "Question", "Answer", "Type", "Double-Jeopardy", "Audio"]
|
||||
|
||||
def __init__(self, qfile):
|
||||
self.qfile = qfile
|
||||
|
@ -72,18 +72,24 @@ class Questions(object):
|
|||
if key not in self.QUESTION_KEYS:
|
||||
raise QuestionException("Qestion %d from section %d (%s) has invalid keyword '%s'" % (j, i, sec["Section"], key))
|
||||
|
||||
# check Double-Jeopardy is a bool and is set to false it non-existant
|
||||
# check Double-Jeopardy is a bool and is set to false if non-existant
|
||||
if "Double-Jeopardy" not in q.keys():
|
||||
q["Double-Jeopardy"] = False
|
||||
elif type(q["Double-Jeopardy"]) != bool:
|
||||
raise QuestionException("The Double-Jeopardy key from question %d from section %d (%s) must be either true or false" % (j, i, sec["Section"]))
|
||||
|
||||
# check Audio is a bool and is set to false if non-existant
|
||||
if "Audio" not in q.keys():
|
||||
q["Audio"] = False
|
||||
elif type(q["Audio"]) != bool:
|
||||
raise QuestionException("The Audio key from question %d from section %d (%s) must be either true or false" % (j, i, sec["Section"]))
|
||||
|
||||
# check for broken question types
|
||||
if q["Type"] not in self.QUESTION_TYPES:
|
||||
raise QuestionException("Question %d from Section %d (%s) has an invalid type '%s' (valid types are %s)" % (j, i, sec["Section"], q["Type"], ", ".join(self.QUESTION_TYPES)))
|
||||
|
||||
# check if file for music/image questions exist
|
||||
if q["Type"] in ("Music", "Image"):
|
||||
if q["Type"] in ("Music", "Image", "Video"):
|
||||
if not os.path.isfile(q["Question"]):
|
||||
raise QuestionException("File for question %d, section %d (%s) not found" % (j, i, sec["Section"]))
|
||||
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
from __future__ import print_function
|
||||
|
||||
from PySide import phonon
|
||||
|
||||
class VideoPlayer(object):
|
||||
def __init__(self, video, audio=False):
|
||||
self._videoFile = video
|
||||
self._audio = audio
|
||||
|
||||
self._widget = None
|
||||
self._media_obj = phonon.Phonon.MediaObject()
|
||||
self._media_src = phonon.Phonon.MediaSource(self._videoFile)
|
||||
|
||||
self._audio_out = None
|
||||
|
||||
# setup media object
|
||||
self._media_obj.setCurrentSource(self._media_src)
|
||||
# make media object loop
|
||||
self._media_obj.finished.connect(lambda: self._media_obj.play())
|
||||
|
||||
if self._audio:
|
||||
self._audio_out = phonon.Phonon.AudioOutput(phonon.Phonon.VideoCategory)
|
||||
phonon.Phonon.createPath(self._media_obj, self._audio_out)
|
||||
|
||||
def get_widget(self):
|
||||
if self._widget == None:
|
||||
self._widget = phonon.Phonon.VideoWidget()
|
||||
self._widget.setScaleMode(phonon.Phonon.VideoWidget.ScaleAndCrop)
|
||||
|
||||
phonon.Phonon.createPath(self._media_obj, self._widget)
|
||||
|
||||
return self._widget
|
||||
|
||||
def play(self):
|
||||
self._media_obj.play()
|
||||
|
||||
def pause(self):
|
||||
self._media_obj.pause()
|
||||
|
||||
def stop(self):
|
||||
self._media_obj.stop()
|
||||
|
26
windows.py
26
windows.py
|
@ -4,6 +4,7 @@ import copy
|
|||
|
||||
from gamestate import QuestionAnswers
|
||||
from music import MusicBox
|
||||
from video import VideoPlayer
|
||||
from player import Player, ButtonEvent, nobodyColor
|
||||
|
||||
class QuestionWindow(QtGui.QDialog):
|
||||
|
@ -20,6 +21,7 @@ class QuestionWindow(QtGui.QDialog):
|
|||
self.dj = dj
|
||||
|
||||
self._windowSetup = False
|
||||
self._videoPlayer = None
|
||||
|
||||
if answers is not None:
|
||||
self.answers = answers
|
||||
|
@ -27,7 +29,7 @@ class QuestionWindow(QtGui.QDialog):
|
|||
self.answers = QuestionAnswers(self.section, self.qnumber)
|
||||
|
||||
if not self.answers.is_answered():
|
||||
if self.question["Type"] != "Music":
|
||||
if not self._question_has_audio():
|
||||
MusicBox.play_music("questionSong")
|
||||
|
||||
if self.dj:
|
||||
|
@ -43,6 +45,8 @@ class QuestionWindow(QtGui.QDialog):
|
|||
tag = "%s-%s" % (self.section, self.qnumber)
|
||||
MusicBox.add_music(tag, self.question["Question"])
|
||||
MusicBox.play_music(tag)
|
||||
elif self.question["Type"] == "Video":
|
||||
self._videoPlayer.play()
|
||||
|
||||
def get_answers(self):
|
||||
return self.answers
|
||||
|
@ -51,6 +55,8 @@ class QuestionWindow(QtGui.QDialog):
|
|||
if not self._inWindow:
|
||||
self.buzzersOpen.emit(False)
|
||||
MusicBox.stop_music()
|
||||
if self._videoPlayer:
|
||||
self._videoPlayer.stop()
|
||||
event.accept()
|
||||
else:
|
||||
event.ignore()
|
||||
|
@ -74,6 +80,7 @@ class QuestionWindow(QtGui.QDialog):
|
|||
self.layout.addStretch()
|
||||
|
||||
qlabel = None
|
||||
stretch = 0
|
||||
if self.question["Type"] == "Text":
|
||||
qlabel = self._mkQuestionLabel(self.question["Question"])
|
||||
elif self.question["Type"] == "Music":
|
||||
|
@ -92,10 +99,15 @@ class QuestionWindow(QtGui.QDialog):
|
|||
code = map(lambda x: x + ((maxLineLen-len(x))*" "), code)
|
||||
|
||||
qlabel = self._mkQuestionLabel("<pre>"+"\n".join(code)+"</pre>", monospaced=True)
|
||||
elif self.question["Type"] == "Video":
|
||||
self._videoPlayer = VideoPlayer(self.question["Question"], self.question["Audio"])
|
||||
qlabel = self._videoPlayer.get_widget()
|
||||
stretch = 1
|
||||
else:
|
||||
raise ValueError("%s is an unknown type for section %s question name %s" % (self.question["Type"], self.section, self.question["Name"]))
|
||||
|
||||
self.layout.addWidget(qlabel)
|
||||
self.layout.addWidget(qlabel, stretch=stretch)
|
||||
|
||||
self.layout.addStretch()
|
||||
|
||||
self.setLayout(self.layout)
|
||||
|
@ -106,6 +118,8 @@ class QuestionWindow(QtGui.QDialog):
|
|||
done = False
|
||||
if self.question["Type"] == "Music":
|
||||
MusicBox.stop_music()
|
||||
elif self.question["Type"] == "Video":
|
||||
self._videoPlayer.pause()
|
||||
|
||||
self._inWindow = True
|
||||
player = self.players[e.get_playerno()-1]
|
||||
|
@ -124,8 +138,11 @@ class QuestionWindow(QtGui.QDialog):
|
|||
if not done:
|
||||
self.buzzersOpen.emit(True)
|
||||
if self.question["Type"] == "Music":
|
||||
# restart music if question was not answered
|
||||
# resume music if question was not answered
|
||||
MusicBox.play_music("%s-%s" % (self.section, self.qnumber))
|
||||
elif self.question["Type"] == "Video":
|
||||
# resume video if question was not answered
|
||||
self._videoPlayer.play()
|
||||
|
||||
elif e.get_playerno() > len(self.players) and not self._inWindow:
|
||||
# unknown player! to not confuse certain devices we send a buttons open event
|
||||
|
@ -158,6 +175,8 @@ class QuestionWindow(QtGui.QDialog):
|
|||
def playerButtonPress(self, no):
|
||||
QtCore.QCoreApplication.postEvent(self, ButtonEvent(int(no)))
|
||||
|
||||
def _question_has_audio(self):
|
||||
return self.question["Type"] == "Music" or (self.question["Type"] == "Video" and self.question["Audio"])
|
||||
|
||||
class QuestionAnswerWindow(QtGui.QDialog):
|
||||
CORRECT = 1
|
||||
|
@ -413,7 +432,6 @@ class PlayerStartWindow(QtGui.QDialog):
|
|||
|
||||
return ret
|
||||
|
||||
|
||||
def closeEvent(self, event):
|
||||
MusicBox.stop_music()
|
||||
self.buzzersOpen.emit(False)
|
||||
|
|
Loading…
Reference in New Issue