From 6b4994c265889db2058b7d5850b51ddfc5478754 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 5 Dec 2012 13:03:09 +0100 Subject: centralize and fixup example sources install targets This follows suit with aeb036e in qtbase. Change-Id: Ie8580d0a1f38ab9858b0e44c9f99bdc552a1752a Reviewed-by: Oswald Buddenhagen Reviewed-by: hjk --- examples/multimediawidgets/player/player.cpp | 428 +++++++++++++++++++++++++++ 1 file changed, 428 insertions(+) create mode 100644 examples/multimediawidgets/player/player.cpp (limited to 'examples/multimediawidgets/player/player.cpp') diff --git a/examples/multimediawidgets/player/player.cpp b/examples/multimediawidgets/player/player.cpp new file mode 100644 index 000000000..fbc3e575e --- /dev/null +++ b/examples/multimediawidgets/player/player.cpp @@ -0,0 +1,428 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "player.h" + +#include "playercontrols.h" +#include "playlistmodel.h" +#include "histogramwidget.h" + +#include +#include +#include +#include + + +Player::Player(QWidget *parent) + : QWidget(parent) + , videoWidget(0) + , coverLabel(0) + , slider(0) +#ifndef PLAYER_NO_COLOROPTIONS + , colorDialog(0) +#endif +{ +//! [create-objs] + player = new QMediaPlayer(this); + // owned by PlaylistModel + playlist = new QMediaPlaylist(); + player->setPlaylist(playlist); +//! [create-objs] + + connect(player, SIGNAL(durationChanged(qint64)), SLOT(durationChanged(qint64))); + connect(player, SIGNAL(positionChanged(qint64)), SLOT(positionChanged(qint64))); + connect(player, SIGNAL(metaDataChanged()), SLOT(metaDataChanged())); + connect(playlist, SIGNAL(currentIndexChanged(int)), SLOT(playlistPositionChanged(int))); + connect(player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), + this, SLOT(statusChanged(QMediaPlayer::MediaStatus))); + connect(player, SIGNAL(bufferStatusChanged(int)), this, SLOT(bufferingProgress(int))); + connect(player, SIGNAL(videoAvailableChanged(bool)), this, SLOT(videoAvailableChanged(bool))); + connect(player, SIGNAL(error(QMediaPlayer::Error)), this, SLOT(displayErrorMessage())); + +//! [2] + videoWidget = new VideoWidget(this); + player->setVideoOutput(videoWidget); + + playlistModel = new PlaylistModel(this); + playlistModel->setPlaylist(playlist); +//! [2] + + playlistView = new QListView(this); + playlistView->setModel(playlistModel); + playlistView->setCurrentIndex(playlistModel->index(playlist->currentIndex(), 0)); + + connect(playlistView, SIGNAL(activated(QModelIndex)), this, SLOT(jump(QModelIndex))); + + slider = new QSlider(Qt::Horizontal, this); + slider->setRange(0, player->duration() / 1000); + + labelDuration = new QLabel(this); + connect(slider, SIGNAL(sliderMoved(int)), this, SLOT(seek(int))); + + labelHistogram = new QLabel(this); + labelHistogram->setText("Histogram:"); + histogram = new HistogramWidget(this); + QHBoxLayout *histogramLayout = new QHBoxLayout; + histogramLayout->addWidget(labelHistogram); + histogramLayout->addWidget(histogram, 1); + + probe = new QVideoProbe(this); + connect(probe, SIGNAL(videoFrameProbed(const QVideoFrame&)), histogram, SLOT(processFrame(QVideoFrame))); + probe->setSource(player); + + QPushButton *openButton = new QPushButton(tr("Open"), this); + + connect(openButton, SIGNAL(clicked()), this, SLOT(open())); + + PlayerControls *controls = new PlayerControls(this); + controls->setState(player->state()); + controls->setVolume(player->volume()); + controls->setMuted(controls->isMuted()); + + connect(controls, SIGNAL(play()), player, SLOT(play())); + connect(controls, SIGNAL(pause()), player, SLOT(pause())); + connect(controls, SIGNAL(stop()), player, SLOT(stop())); + connect(controls, SIGNAL(next()), playlist, SLOT(next())); + connect(controls, SIGNAL(previous()), this, SLOT(previousClicked())); + connect(controls, SIGNAL(changeVolume(int)), player, SLOT(setVolume(int))); + connect(controls, SIGNAL(changeMuting(bool)), player, SLOT(setMuted(bool))); + connect(controls, SIGNAL(changeRate(qreal)), player, SLOT(setPlaybackRate(qreal))); + + connect(controls, SIGNAL(stop()), videoWidget, SLOT(update())); + + connect(player, SIGNAL(stateChanged(QMediaPlayer::State)), + controls, SLOT(setState(QMediaPlayer::State))); + connect(player, SIGNAL(volumeChanged(int)), controls, SLOT(setVolume(int))); + connect(player, SIGNAL(mutedChanged(bool)), controls, SLOT(setMuted(bool))); + + fullScreenButton = new QPushButton(tr("FullScreen"), this); + fullScreenButton->setCheckable(true); + +#ifndef PLAYER_NO_COLOROPTIONS + colorButton = new QPushButton(tr("Color Options..."), this); + colorButton->setEnabled(false); + connect(colorButton, SIGNAL(clicked()), this, SLOT(showColorDialog())); +#endif + + QBoxLayout *displayLayout = new QHBoxLayout; + displayLayout->addWidget(videoWidget, 2); + displayLayout->addWidget(playlistView); + + QBoxLayout *controlLayout = new QHBoxLayout; + controlLayout->setMargin(0); + controlLayout->addWidget(openButton); + controlLayout->addStretch(1); + controlLayout->addWidget(controls); + controlLayout->addStretch(1); + controlLayout->addWidget(fullScreenButton); +#ifndef PLAYER_NO_COLOROPTIONS + controlLayout->addWidget(colorButton); +#endif + + QBoxLayout *layout = new QVBoxLayout; + layout->addLayout(displayLayout); + QHBoxLayout *hLayout = new QHBoxLayout; + hLayout->addWidget(slider); + hLayout->addWidget(labelDuration); + layout->addLayout(hLayout); + layout->addLayout(controlLayout); + layout->addLayout(histogramLayout); + + setLayout(layout); + + if (!player->isAvailable()) { + QMessageBox::warning(this, tr("Service not available"), + tr("The QMediaPlayer object does not have a valid service.\n"\ + "Please check the media service plugins are installed.")); + + controls->setEnabled(false); + playlistView->setEnabled(false); + openButton->setEnabled(false); +#ifndef PLAYER_NO_COLOROPTIONS + colorButton->setEnabled(false); +#endif + fullScreenButton->setEnabled(false); + } + + metaDataChanged(); + + QStringList arguments = qApp->arguments(); + arguments.removeAt(0); + addToPlaylist(arguments); +} + +Player::~Player() +{ +} + +void Player::open() +{ + QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Open Files")); + addToPlaylist(fileNames); +} + +void Player::addToPlaylist(const QStringList& fileNames) +{ + foreach (QString const &argument, fileNames) { + QFileInfo fileInfo(argument); + if (fileInfo.exists()) { + QUrl url = QUrl::fromLocalFile(fileInfo.absoluteFilePath()); + if (fileInfo.suffix().toLower() == QLatin1String("m3u")) { + playlist->load(url); + } else + playlist->addMedia(url); + } else { + QUrl url(argument); + if (url.isValid()) { + playlist->addMedia(url); + } + } + } +} + +void Player::durationChanged(qint64 duration) +{ + this->duration = duration/1000; + slider->setMaximum(duration / 1000); +} + +void Player::positionChanged(qint64 progress) +{ + if (!slider->isSliderDown()) { + slider->setValue(progress / 1000); + } + updateDurationInfo(progress / 1000); +} + +void Player::metaDataChanged() +{ + if (player->isMetaDataAvailable()) { + setTrackInfo(QString("%1 - %2") + .arg(player->metaData(QMediaMetaData::AlbumArtist).toString()) + .arg(player->metaData(QMediaMetaData::Title).toString())); + + if (coverLabel) { + QUrl url = player->metaData(QMediaMetaData::CoverArtUrlLarge).value(); + + coverLabel->setPixmap(!url.isEmpty() + ? QPixmap(url.toString()) + : QPixmap()); + } + } +} + +void Player::previousClicked() +{ + // Go to previous track if we are within the first 5 seconds of playback + // Otherwise, seek to the beginning. + if(player->position() <= 5000) + playlist->previous(); + else + player->setPosition(0); +} + +void Player::jump(const QModelIndex &index) +{ + if (index.isValid()) { + playlist->setCurrentIndex(index.row()); + player->play(); + } +} + +void Player::playlistPositionChanged(int currentItem) +{ + playlistView->setCurrentIndex(playlistModel->index(currentItem, 0)); +} + +void Player::seek(int seconds) +{ + player->setPosition(seconds * 1000); +} + +void Player::statusChanged(QMediaPlayer::MediaStatus status) +{ + handleCursor(status); + + // handle status message + switch (status) { + case QMediaPlayer::UnknownMediaStatus: + case QMediaPlayer::NoMedia: + case QMediaPlayer::LoadedMedia: + case QMediaPlayer::BufferingMedia: + case QMediaPlayer::BufferedMedia: + setStatusInfo(QString()); + break; + case QMediaPlayer::LoadingMedia: + setStatusInfo(tr("Loading...")); + break; + case QMediaPlayer::StalledMedia: + setStatusInfo(tr("Media Stalled")); + break; + case QMediaPlayer::EndOfMedia: + QApplication::alert(this); + break; + case QMediaPlayer::InvalidMedia: + displayErrorMessage(); + break; + } +} + +void Player::handleCursor(QMediaPlayer::MediaStatus status) +{ +#ifndef QT_NO_CURSOR + if (status == QMediaPlayer::LoadingMedia || + status == QMediaPlayer::BufferingMedia || + status == QMediaPlayer::StalledMedia) + setCursor(QCursor(Qt::BusyCursor)); + else + unsetCursor(); +#endif +} + +void Player::bufferingProgress(int progress) +{ + setStatusInfo(tr("Buffering %4%").arg(progress)); +} + +void Player::videoAvailableChanged(bool available) +{ + if (!available) { + disconnect(fullScreenButton, SIGNAL(clicked(bool)), + videoWidget, SLOT(setFullScreen(bool))); + disconnect(videoWidget, SIGNAL(fullScreenChanged(bool)), + fullScreenButton, SLOT(setChecked(bool))); + videoWidget->setFullScreen(false); + } else { + connect(fullScreenButton, SIGNAL(clicked(bool)), + videoWidget, SLOT(setFullScreen(bool))); + connect(videoWidget, SIGNAL(fullScreenChanged(bool)), + fullScreenButton, SLOT(setChecked(bool))); + + if (fullScreenButton->isChecked()) + videoWidget->setFullScreen(true); + } +#ifndef PLAYER_NO_COLOROPTIONS + colorButton->setEnabled(available); +#endif +} + +void Player::setTrackInfo(const QString &info) +{ + trackInfo = info; + if (!statusInfo.isEmpty()) + setWindowTitle(QString("%1 | %2").arg(trackInfo).arg(statusInfo)); + else + setWindowTitle(trackInfo); +} + +void Player::setStatusInfo(const QString &info) +{ + statusInfo = info; + if (!statusInfo.isEmpty()) + setWindowTitle(QString("%1 | %2").arg(trackInfo).arg(statusInfo)); + else + setWindowTitle(trackInfo); +} + +void Player::displayErrorMessage() +{ + setStatusInfo(player->errorString()); +} + +void Player::updateDurationInfo(qint64 currentInfo) +{ + QString tStr; + if (currentInfo || duration) { + QTime currentTime((currentInfo/3600)%60, (currentInfo/60)%60, currentInfo%60, (currentInfo*1000)%1000); + QTime totalTime((duration/3600)%60, (duration/60)%60, duration%60, (duration*1000)%1000); + QString format = "mm:ss"; + if (duration > 3600) + format = "hh:mm:ss"; + tStr = currentTime.toString(format) + " / " + totalTime.toString(format); + } + labelDuration->setText(tStr); +} + +#ifndef PLAYER_NO_COLOROPTIONS +void Player::showColorDialog() +{ + if (!colorDialog) { + QSlider *brightnessSlider = new QSlider(Qt::Horizontal); + brightnessSlider->setRange(-100, 100); + brightnessSlider->setValue(videoWidget->brightness()); + connect(brightnessSlider, SIGNAL(sliderMoved(int)), videoWidget, SLOT(setBrightness(int))); + connect(videoWidget, SIGNAL(brightnessChanged(int)), brightnessSlider, SLOT(setValue(int))); + + QSlider *contrastSlider = new QSlider(Qt::Horizontal); + contrastSlider->setRange(-100, 100); + contrastSlider->setValue(videoWidget->contrast()); + connect(contrastSlider, SIGNAL(sliderMoved(int)), videoWidget, SLOT(setContrast(int))); + connect(videoWidget, SIGNAL(contrastChanged(int)), contrastSlider, SLOT(setValue(int))); + + QSlider *hueSlider = new QSlider(Qt::Horizontal); + hueSlider->setRange(-100, 100); + hueSlider->setValue(videoWidget->hue()); + connect(hueSlider, SIGNAL(sliderMoved(int)), videoWidget, SLOT(setHue(int))); + connect(videoWidget, SIGNAL(hueChanged(int)), hueSlider, SLOT(setValue(int))); + + QSlider *saturationSlider = new QSlider(Qt::Horizontal); + saturationSlider->setRange(-100, 100); + saturationSlider->setValue(videoWidget->saturation()); + connect(saturationSlider, SIGNAL(sliderMoved(int)), videoWidget, SLOT(setSaturation(int))); + connect(videoWidget, SIGNAL(saturationChanged(int)), saturationSlider, SLOT(setValue(int))); + + QFormLayout *layout = new QFormLayout; + layout->addRow(tr("Brightness"), brightnessSlider); + layout->addRow(tr("Contrast"), contrastSlider); + layout->addRow(tr("Hue"), hueSlider); + layout->addRow(tr("Saturation"), saturationSlider); + + QPushButton *button = new QPushButton(tr("Close")); + layout->addRow(button); + + colorDialog = new QDialog(this); + colorDialog->setWindowTitle(tr("Color Options")); + colorDialog->setLayout(layout); + + connect(button, SIGNAL(clicked()), colorDialog, SLOT(close())); + } + colorDialog->show(); +} +#endif -- cgit v1.2.3