1 /****************************************************************************
2 **
3 ** Copyright (C) 2017 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the examples of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:BSD$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** BSD License Usage
18 ** Alternatively, you may use this file under the terms of the BSD license
19 ** as follows:
20 **
21 ** "Redistribution and use in source and binary forms, with or without
22 ** modification, are permitted provided that the following conditions are
23 ** met:
24 ** * Redistributions of source code must retain the above copyright
25 ** notice, this list of conditions and the following disclaimer.
26 ** * Redistributions in binary form must reproduce the above copyright
27 ** notice, this list of conditions and the following disclaimer in
28 ** the documentation and/or other materials provided with the
29 ** distribution.
30 ** * Neither the name of The Qt Company Ltd nor the names of its
31 ** contributors may be used to endorse or promote products derived
32 ** from this software without specific prior written permission.
33 **
34 **
35 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
46 **
47 ** $QT_END_LICENSE$
48 **
49 ****************************************************************************/
50
51 #include "videoplayer.h"
52 #include "videoitem.h"
53
54 #include <QtWidgets>
55 #include <QVideoSurfaceFormat>
56
57 #if !defined(QT_NO_OPENGL)
58 # include <QOpenGLWidget>
59 #endif
60
VideoPlayer(QWidget * parent)61 VideoPlayer::VideoPlayer(QWidget *parent)
62 : QWidget(parent)
63 , mediaPlayer(0, QMediaPlayer::VideoSurface)
64 , videoItem(0)
65 , playButton(0)
66 , positionSlider(0)
67 {
68 videoItem = new VideoItem;
69
70 QGraphicsScene *scene = new QGraphicsScene(this);
71 QGraphicsView *graphicsView = new QGraphicsView(scene);
72
73 #if !defined(QT_NO_OPENGL)
74 graphicsView->setViewport(new QOpenGLWidget);
75 #endif
76
77 scene->addItem(videoItem);
78
79 QSlider *rotateSlider = new QSlider(Qt::Horizontal);
80 rotateSlider->setRange(-180, 180);
81 rotateSlider->setValue(0);
82
83 connect(rotateSlider, &QSlider::valueChanged,
84 this, &VideoPlayer::rotateVideo);
85
86 QAbstractButton *openButton = new QPushButton(tr("Open..."));
87 connect(openButton, &QAbstractButton::clicked,
88 this, &VideoPlayer::openFile);
89
90 playButton = new QPushButton;
91 playButton->setEnabled(false);
92 playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay));
93
94 connect(playButton, &QAbstractButton::clicked,
95 this, &VideoPlayer::play);
96
97 positionSlider = new QSlider(Qt::Horizontal);
98 positionSlider->setRange(0, 0);
99
100 connect(positionSlider, &QSlider::sliderMoved,
101 this, &VideoPlayer::setPosition);
102
103 QBoxLayout *controlLayout = new QHBoxLayout;
104 controlLayout->setContentsMargins(0, 0, 0, 0);
105 controlLayout->addWidget(openButton);
106 controlLayout->addWidget(playButton);
107 controlLayout->addWidget(positionSlider);
108
109 QBoxLayout *layout = new QVBoxLayout;
110 layout->addWidget(graphicsView);
111 layout->addWidget(rotateSlider);
112 layout->addLayout(controlLayout);
113
114 setLayout(layout);
115
116 mediaPlayer.setVideoOutput(videoItem);
117 connect(&mediaPlayer, &QMediaPlayer::stateChanged,
118 this, &VideoPlayer::mediaStateChanged);
119 connect(&mediaPlayer, &QMediaPlayer::positionChanged, this, &VideoPlayer::positionChanged);
120 connect(&mediaPlayer, &QMediaPlayer::durationChanged, this, &VideoPlayer::durationChanged);
121 }
122
~VideoPlayer()123 VideoPlayer::~VideoPlayer()
124 {
125 }
126
127
openFile()128 void VideoPlayer::openFile()
129 {
130 QString fileName = QFileDialog::getOpenFileName(this, tr("Open Movie"),QDir::homePath());
131
132 if (!fileName.isEmpty()) {
133 mediaPlayer.setMedia(QUrl::fromLocalFile(fileName));
134
135 playButton->setEnabled(true);
136 }
137 }
138
play()139 void VideoPlayer::play()
140 {
141 switch(mediaPlayer.state()) {
142 case QMediaPlayer::PlayingState:
143 mediaPlayer.pause();
144 break;
145 default:
146 mediaPlayer.play();
147 break;
148 }
149 }
150
mediaStateChanged(QMediaPlayer::State state)151 void VideoPlayer::mediaStateChanged(QMediaPlayer::State state)
152 {
153 switch(state) {
154 case QMediaPlayer::PlayingState:
155 playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPause));
156 break;
157 default:
158 playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay));
159 break;
160 }
161 }
162
positionChanged(qint64 position)163 void VideoPlayer::positionChanged(qint64 position)
164 {
165 positionSlider->setValue(position);
166 }
167
durationChanged(qint64 duration)168 void VideoPlayer::durationChanged(qint64 duration)
169 {
170 positionSlider->setRange(0, duration);
171 }
172
setPosition(int position)173 void VideoPlayer::setPosition(int position)
174 {
175 mediaPlayer.setPosition(position);
176 }
177
178
rotateVideo(int angle)179 void VideoPlayer::rotateVideo(int angle)
180 {
181 //rotate around the center of video element
182 qreal x = videoItem->boundingRect().width() / 2.0;
183 qreal y = videoItem->boundingRect().height() / 2.0;
184 videoItem->setTransform(QTransform().translate(x, y).rotate(angle).translate(-x, -y));
185 }
186