mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
playback/player: Add Qt bindings and player
This commit is contained in:
parent
09864feff4
commit
82b2c53618
14 changed files with 1606 additions and 0 deletions
27
playback/player/qt/deployment.pri
Normal file
27
playback/player/qt/deployment.pri
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
android-no-sdk {
|
||||||
|
target.path = /data/user/qt
|
||||||
|
export(target.path)
|
||||||
|
INSTALLS += target
|
||||||
|
} else:android {
|
||||||
|
x86 {
|
||||||
|
target.path = /libs/x86
|
||||||
|
} else: armeabi-v7a {
|
||||||
|
target.path = /libs/armeabi-v7a
|
||||||
|
} else {
|
||||||
|
target.path = /libs/armeabi
|
||||||
|
}
|
||||||
|
export(target.path)
|
||||||
|
INSTALLS += target
|
||||||
|
} else:unix {
|
||||||
|
isEmpty(target.path) {
|
||||||
|
qnx {
|
||||||
|
target.path = /tmp/$${TARGET}/bin
|
||||||
|
} else {
|
||||||
|
target.path = /opt/$${TARGET}/bin
|
||||||
|
}
|
||||||
|
export(target.path)
|
||||||
|
}
|
||||||
|
INSTALLS += target
|
||||||
|
}
|
||||||
|
|
||||||
|
export(INSTALLS)
|
BIN
playback/player/qt/fontawesome-webfont.ttf
Normal file
BIN
playback/player/qt/fontawesome-webfont.ttf
Normal file
Binary file not shown.
10
playback/player/qt/fontawesome-webfont.ttf.txt
Normal file
10
playback/player/qt/fontawesome-webfont.ttf.txt
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
|
||||||
|
Font Awesome
|
||||||
|
|
||||||
|
URL: http://fontawesome.io
|
||||||
|
|
||||||
|
Font License
|
||||||
|
|
||||||
|
License: SIL OFL 1.1
|
||||||
|
URL: http://scripts.sil.org/OFL
|
||||||
|
|
214
playback/player/qt/fontawesome.js
Normal file
214
playback/player/qt/fontawesome.js
Normal file
|
@ -0,0 +1,214 @@
|
||||||
|
var Icon = {
|
||||||
|
Glass : "\uf000",
|
||||||
|
Music : "\uf001",
|
||||||
|
Search : "\uf002",
|
||||||
|
Envelope : "\uf003",
|
||||||
|
Heart : "\uf004",
|
||||||
|
Star : "\uf005",
|
||||||
|
StarEmpty : "\uf006",
|
||||||
|
User : "\uf007",
|
||||||
|
Film : "\uf008",
|
||||||
|
ThLarge : "\uf009",
|
||||||
|
Th : "\uf00a",
|
||||||
|
ThList : "\uf00b",
|
||||||
|
Ok : "\uf00c",
|
||||||
|
Remove : "\uf00d",
|
||||||
|
ZoomIn : "\uf00e",
|
||||||
|
ZoomOut : "\uf010",
|
||||||
|
Off : "\uf011",
|
||||||
|
Signal : "\uf012",
|
||||||
|
Cog : "\uf013",
|
||||||
|
Trash : "\uf014",
|
||||||
|
Home : "\uf015",
|
||||||
|
File : "\uf016",
|
||||||
|
Time : "\uf017",
|
||||||
|
Road : "\uf018",
|
||||||
|
DownloadAlt : "\uf019",
|
||||||
|
Download : "\uf01a",
|
||||||
|
Upload : "\uf01b",
|
||||||
|
Inbox : "\uf01c",
|
||||||
|
PlayCircle : "\uf01d",
|
||||||
|
Repeat : "\uf01e",
|
||||||
|
Refresh : "\uf021",
|
||||||
|
ListAlt : "\uf022",
|
||||||
|
Lock : "\uf023",
|
||||||
|
Flag : "\uf024",
|
||||||
|
Headphones : "\uf025",
|
||||||
|
VolumeOff : "\uf026",
|
||||||
|
VolumeDown : "\uf027",
|
||||||
|
VolumeUp : "\uf028",
|
||||||
|
Qrcode : "\uf029",
|
||||||
|
Barcode : "\uf02a",
|
||||||
|
Tag : "\uf02b",
|
||||||
|
Tags : "\uf02c",
|
||||||
|
Book : "\uf02d",
|
||||||
|
Bookmark : "\uf02e",
|
||||||
|
Print : "\uf02f",
|
||||||
|
Camera : "\uf030",
|
||||||
|
Font : "\uf031",
|
||||||
|
Bold : "\uf032",
|
||||||
|
Italic : "\uf033",
|
||||||
|
TextHeight : "\uf034",
|
||||||
|
TextWidth : "\uf035",
|
||||||
|
AlignLeft : "\uf036",
|
||||||
|
AlignCenter : "\uf037",
|
||||||
|
AlignRight : "\uf038",
|
||||||
|
AlignJustify : "\uf039",
|
||||||
|
List : "\uf03a",
|
||||||
|
IndentLeft : "\uf03b",
|
||||||
|
IndentRight : "\uf03c",
|
||||||
|
FacetimeVideo : "\uf03d",
|
||||||
|
Picture : "\uf03e",
|
||||||
|
Pencil : "\uf040",
|
||||||
|
MapMarker : "\uf041",
|
||||||
|
Adjust : "\uf042",
|
||||||
|
Tint : "\uf043",
|
||||||
|
Edit : "\uf044",
|
||||||
|
Share : "\uf045",
|
||||||
|
Check : "\uf046",
|
||||||
|
Move : "\uf047",
|
||||||
|
StepBackward : "\uf048",
|
||||||
|
StepForward : "\uf049",
|
||||||
|
Backward : "\uf04a",
|
||||||
|
Play : "\uf04b",
|
||||||
|
Pause : "\uf04c",
|
||||||
|
Stop : "\uf04d",
|
||||||
|
Forward : "\uf04e",
|
||||||
|
FastForward : "\uf050",
|
||||||
|
StepForward : "\uf051",
|
||||||
|
Eject : "\uf052",
|
||||||
|
ChevronLeft : "\uf053",
|
||||||
|
ChevronRight : "\uf054",
|
||||||
|
PlusSign : "\uf055",
|
||||||
|
MinusSign : "\uf056",
|
||||||
|
RemoveSign : "\uf057",
|
||||||
|
OkSign : "\uf058",
|
||||||
|
QuestionSign : "\uf059",
|
||||||
|
InfoSign : "\uf05a",
|
||||||
|
Screenshot : "\uf05b",
|
||||||
|
RemoveCircle : "\uf05c",
|
||||||
|
OkCircle : "\uf05d",
|
||||||
|
BanCircle : "\uf05e",
|
||||||
|
ArrowLeft : "\uf060",
|
||||||
|
ArrowRight : "\uf061",
|
||||||
|
ArrowUp : "\uf062",
|
||||||
|
ArrowDown : "\uf063",
|
||||||
|
ShareAlt : "\uf064",
|
||||||
|
ResizeFull : "\uf065",
|
||||||
|
ResizeSmall : "\uf066",
|
||||||
|
Plus : "\uf067",
|
||||||
|
Minus : "\uf068",
|
||||||
|
Asterish : "\uf069",
|
||||||
|
ExclamationSign : "\uf06a",
|
||||||
|
Gift : "\uf06b",
|
||||||
|
Leave : "\uf06c",
|
||||||
|
Fire : "\uf06d",
|
||||||
|
EyeOpen : "\uf06e",
|
||||||
|
EyeClose : "\uf070",
|
||||||
|
WarningSign : "\uf071",
|
||||||
|
Plane : "\uf072",
|
||||||
|
Calendar : "\uf073",
|
||||||
|
Random : "\uf074",
|
||||||
|
Comment : "\uf075",
|
||||||
|
Magnet : "\uf076",
|
||||||
|
ChevronUp : "\uf077",
|
||||||
|
ChevronDown : "\uf078",
|
||||||
|
Retweet : "\uf079",
|
||||||
|
ShoppingCart : "\uf07a",
|
||||||
|
FolderClose : "\uf07b",
|
||||||
|
FolderOpen : "\uf07c",
|
||||||
|
ResizeVertical : "\uf07d",
|
||||||
|
ResizeHorizontal : "\uf07e",
|
||||||
|
BarChart : "\uf080",
|
||||||
|
TwitterSign : "\uf081",
|
||||||
|
FacebookSign : "\uf082",
|
||||||
|
CameraRetro : "\uf083",
|
||||||
|
Key : "\uf084",
|
||||||
|
Cogs : "\uf085",
|
||||||
|
Comments : "\uf086",
|
||||||
|
ThumbsUp : "\uf087",
|
||||||
|
ThumbsDown : "\uf088",
|
||||||
|
StarHalf : "\uf089",
|
||||||
|
HeartEmpty : "\uf08a",
|
||||||
|
Signout : "\uf08b",
|
||||||
|
LinkedinSign : "\uf08c",
|
||||||
|
Pushpin : "\uf08d",
|
||||||
|
ExternalLink : "\uf08e",
|
||||||
|
Signin : "\uf090",
|
||||||
|
Trophy : "\uf091",
|
||||||
|
GithubSign : "\uf092",
|
||||||
|
UploadAlt : "\uf093",
|
||||||
|
Lemon : "\uf094",
|
||||||
|
Phone : "\uf095",
|
||||||
|
CheckEmpty : "\uf096",
|
||||||
|
BookmarkEmpty : "\uf097",
|
||||||
|
PhoneSign : "\uf098",
|
||||||
|
Twitter : "\uf099",
|
||||||
|
Facebook : "\uf09a",
|
||||||
|
Github : "\uf09b",
|
||||||
|
Unlock : "\uf09c",
|
||||||
|
CreditCard : "\uf09d",
|
||||||
|
Rss : "\uf09e",
|
||||||
|
Hdd : "\uf0a0",
|
||||||
|
Bullhorn : "\uf0a1",
|
||||||
|
Bell : "\uf0a2",
|
||||||
|
Certificate : "\uf0a3",
|
||||||
|
HandRight : "\uf0a4",
|
||||||
|
HandLeft : "\uf0a5",
|
||||||
|
HandUp : "\uf0a6",
|
||||||
|
HandDown : "\uf0a7",
|
||||||
|
CircleArrowLeft : "\uf0a8",
|
||||||
|
CircleArrowRight : "\uf0a9",
|
||||||
|
CircleArrowUp : "\uf0aa",
|
||||||
|
CircleArrowDown : "\uf0ab",
|
||||||
|
Globe : "\uf0ac",
|
||||||
|
Wrench : "\uf0ad",
|
||||||
|
Tasks : "\uf0ae",
|
||||||
|
Filter : "\uf0b0",
|
||||||
|
Briefcase : "\uf0b1",
|
||||||
|
Fullscreen : "\uf0b2",
|
||||||
|
Group : "\uf0c0",
|
||||||
|
Link : "\uf0c1",
|
||||||
|
Cloud : "\uf0c2",
|
||||||
|
Beaker : "\uf0c3",
|
||||||
|
Cut : "\uf0c4",
|
||||||
|
Copy : "\uf0c5",
|
||||||
|
PaperClip : "\uf0c6",
|
||||||
|
Save : "\uf0c7",
|
||||||
|
SignBlank : "\uf0c8",
|
||||||
|
Reorder : "\uf0c9",
|
||||||
|
ListUl : "\uf0ca",
|
||||||
|
ListOl : "\uf0cb",
|
||||||
|
Strikethrough : "\uf0cc",
|
||||||
|
Underline : "\uf0cd",
|
||||||
|
Table : "\uf0ce",
|
||||||
|
Magic : "\uf0d0",
|
||||||
|
Truck : "\uf0d1",
|
||||||
|
Pinterest : "\uf0d2",
|
||||||
|
PinterestSign : "\uf0d3",
|
||||||
|
GooglePlusSign : "\uf0d4",
|
||||||
|
GooglePlus : "\uf0d5",
|
||||||
|
Money : "\uf0d6",
|
||||||
|
CaretDown : "\uf0d7",
|
||||||
|
CaretUp : "\uf0d8",
|
||||||
|
CaretLeft : "\uf0d9",
|
||||||
|
CaretRight : "\uf0da",
|
||||||
|
Columns : "\uf0db",
|
||||||
|
Sort : "\uf0dc",
|
||||||
|
SortDown : "\uf0dd",
|
||||||
|
SortUp : "\uf0de",
|
||||||
|
EnvelopeAlt : "\uf0e0",
|
||||||
|
Linkedin : "\uf0e1",
|
||||||
|
Undo : "\uf0e2",
|
||||||
|
Legal : "\uf0e3",
|
||||||
|
Dashboard : "\uf0e4",
|
||||||
|
CommentAlt : "\uf0e5",
|
||||||
|
CommentsAlt : "\uf0e6",
|
||||||
|
Bolt : "\uf0e7",
|
||||||
|
Sitemap : "\uf0e8",
|
||||||
|
Unbrella : "\uf0e9",
|
||||||
|
Paste : "\uf0ea",
|
||||||
|
ClosedCaptions : "\uf20a",
|
||||||
|
UserMd : "\uf200",
|
||||||
|
};
|
||||||
|
|
52
playback/player/qt/main.cpp
Normal file
52
playback/player/qt/main.cpp
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/* GStreamer
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015 Alexandre Moreno <alexmorenocano@gmail.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QQmlApplicationEngine>
|
||||||
|
|
||||||
|
#include "player.h"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
QGuiApplication app(argc, argv);
|
||||||
|
|
||||||
|
qmlRegisterType<Player>("Player", 1, 0, "Player");
|
||||||
|
|
||||||
|
/* the plugin must be loaded before loading the qml file to register the
|
||||||
|
* GstGLVideoItem qml item
|
||||||
|
* FIXME Add a QQmlExtensionPlugin into qmlglsink to register GstGLVideoItem
|
||||||
|
* with the QML engine, then remove this */
|
||||||
|
gst_init(NULL,NULL);
|
||||||
|
GstElement *sink = gst_element_factory_make ("qmlglsink", NULL);
|
||||||
|
gst_object_unref(sink);
|
||||||
|
|
||||||
|
|
||||||
|
QQmlApplicationEngine engine;
|
||||||
|
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
|
||||||
|
|
||||||
|
QObject *rootObject = engine.rootObjects().first();
|
||||||
|
|
||||||
|
Player *player = rootObject->findChild<Player*>("player");
|
||||||
|
QQuickItem *videoItem = rootObject->findChild<QQuickItem*>("videoItem");
|
||||||
|
player->setVideoOutput(videoItem);
|
||||||
|
|
||||||
|
|
||||||
|
return app.exec();
|
||||||
|
}
|
461
playback/player/qt/main.qml
Normal file
461
playback/player/qt/main.qml
Normal file
|
@ -0,0 +1,461 @@
|
||||||
|
/* GStreamer
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015 Alexandre Moreno <alexmorenocano@gmail.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.4
|
||||||
|
import QtQuick.Controls 1.1
|
||||||
|
import QtQuick.Controls.Styles 1.3
|
||||||
|
import QtQuick.Dialogs 1.2
|
||||||
|
import QtQuick.Window 2.1
|
||||||
|
import Player 1.0
|
||||||
|
import org.freedesktop.gstreamer.GLVideoItem 1.0
|
||||||
|
|
||||||
|
import "fontawesome.js" as FontAwesome
|
||||||
|
|
||||||
|
ApplicationWindow {
|
||||||
|
id: window
|
||||||
|
visible: true
|
||||||
|
width: 640
|
||||||
|
height: 480
|
||||||
|
x: 30
|
||||||
|
y: 30
|
||||||
|
color: "black"
|
||||||
|
// title : player.mediaInfo.title
|
||||||
|
|
||||||
|
Player {
|
||||||
|
id: player
|
||||||
|
objectName: "player"
|
||||||
|
volume: 0.5
|
||||||
|
onStateChanged: {
|
||||||
|
if (state === Player.STOPPED) {
|
||||||
|
playbutton.text = FontAwesome.Icon.Play
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onResolutionChanged: {
|
||||||
|
if (player.videoAvailable) {
|
||||||
|
window.width = resolution.width
|
||||||
|
window.height = resolution.height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GstGLVideoItem {
|
||||||
|
id: video
|
||||||
|
objectName: "videoItem"
|
||||||
|
anchors.centerIn: parent
|
||||||
|
width: 640
|
||||||
|
height: 480
|
||||||
|
}
|
||||||
|
|
||||||
|
FileDialog {
|
||||||
|
id: fileDialog
|
||||||
|
//nameFilters: [TODO globs from mime types]
|
||||||
|
onAccepted: player.source = fileUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
Action {
|
||||||
|
id: fileOpenAction
|
||||||
|
text: "Open"
|
||||||
|
onTriggered: fileDialog.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
menuBar: MenuBar {
|
||||||
|
Menu {
|
||||||
|
title: "&File"
|
||||||
|
MenuItem { action: fileOpenAction }
|
||||||
|
MenuItem { text: "Quit"; onTriggered: Qt.quit() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
anchors.fill: parent
|
||||||
|
FontLoader {
|
||||||
|
source: "fonts/fontawesome-webfont.ttf"
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id : playbar
|
||||||
|
color: Qt.rgba(1, 1, 1, 0.7)
|
||||||
|
border.width: 1
|
||||||
|
border.color: "white"
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.bottomMargin: 15
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
width : grid.width + 20
|
||||||
|
height: 40//childrenRect.height + 20
|
||||||
|
radius: 5
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: mousearea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
onEntered: {
|
||||||
|
parent.opacity = 1.0
|
||||||
|
hidetimer.start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: hidetimer
|
||||||
|
interval: 10000
|
||||||
|
onTriggered: {
|
||||||
|
parent.opacity = 0.0
|
||||||
|
stop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Grid {
|
||||||
|
id: grid
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
// anchors.top: parent.top
|
||||||
|
// anchors.topMargin: 5
|
||||||
|
|
||||||
|
spacing: 7
|
||||||
|
rows: 1
|
||||||
|
verticalItemAlignment: Qt.AlignVCenter
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id : openmedia
|
||||||
|
font.pointSize: 17
|
||||||
|
font.family: "FontAwesome"
|
||||||
|
text: FontAwesome.Icon.FolderOpen
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onPressed: fileDialog.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: 17
|
||||||
|
height: 17
|
||||||
|
|
||||||
|
Text {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
font.pointSize: 17
|
||||||
|
font.family: "FontAwesome"
|
||||||
|
text: FontAwesome.Icon.StepBackward
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: 25
|
||||||
|
height: 25
|
||||||
|
|
||||||
|
Text {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
id : playbutton
|
||||||
|
font.pointSize: 25
|
||||||
|
font.family: "FontAwesome"
|
||||||
|
//font.weight: Font.Light
|
||||||
|
text: FontAwesome.Icon.PlayCircle
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: playArea
|
||||||
|
anchors.fill: parent
|
||||||
|
onPressed: {
|
||||||
|
if (player.state !== Player.PLAYING) {
|
||||||
|
player.play()
|
||||||
|
playbutton.text = FontAwesome.Icon.Pause
|
||||||
|
playbutton.font.pointSize = 17
|
||||||
|
} else {
|
||||||
|
player.pause()
|
||||||
|
playbutton.text = FontAwesome.Icon.PlayCircle
|
||||||
|
playbutton.font.pointSize = 25
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: 17
|
||||||
|
height: 17
|
||||||
|
|
||||||
|
Text {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
font.pointSize: 17
|
||||||
|
font.family: "FontAwesome"
|
||||||
|
text: FontAwesome.Icon.StepForward
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: 40
|
||||||
|
height: 17
|
||||||
|
Text {
|
||||||
|
id: timelabel
|
||||||
|
anchors.centerIn: parent
|
||||||
|
font.pointSize: 13
|
||||||
|
color: "black"
|
||||||
|
text: {
|
||||||
|
var current = new Date(Math.floor(slider.value / 1e6));
|
||||||
|
current.getMinutes() + ":" + ('0'+current.getSeconds()).slice(-2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: 200
|
||||||
|
height: 38
|
||||||
|
Text {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: player.mediaInfo.title
|
||||||
|
font.pointSize: 15
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: 40
|
||||||
|
height: 17
|
||||||
|
Text {
|
||||||
|
id: durationlabel
|
||||||
|
anchors.centerIn: parent
|
||||||
|
font.pointSize: 13
|
||||||
|
color: "black"
|
||||||
|
text: {
|
||||||
|
var duration = new Date(Math.floor(player.duration / 1e6));
|
||||||
|
duration.getMinutes() + ":" + ('0'+duration.getSeconds()).slice(-2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: 17
|
||||||
|
height: 17
|
||||||
|
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id : volume
|
||||||
|
anchors.centerIn: parent
|
||||||
|
font.pointSize: 17
|
||||||
|
font.family: "FontAwesome"
|
||||||
|
text: {
|
||||||
|
if (volumeslider.value > volumeslider.maximumValue / 2) {
|
||||||
|
FontAwesome.Icon.VolumeUp
|
||||||
|
} else if (volumeslider.value === 0) {
|
||||||
|
FontAwesome.Icon.VolumeOff
|
||||||
|
} else {
|
||||||
|
FontAwesome.Icon.VolumeDown
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id : volumebar
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.bottom: parent.top
|
||||||
|
//anchors.bottomMargin:3
|
||||||
|
color: "lightgray"
|
||||||
|
width: 17
|
||||||
|
height: 66
|
||||||
|
visible: false
|
||||||
|
radius: 5
|
||||||
|
|
||||||
|
Slider {
|
||||||
|
id: volumeslider
|
||||||
|
value: player.volume
|
||||||
|
minimumValue: 0.0
|
||||||
|
maximumValue: 1.0
|
||||||
|
stepSize: 0.001
|
||||||
|
anchors.centerIn: parent
|
||||||
|
orientation: Qt.Vertical
|
||||||
|
onPressedChanged: player.volume = value
|
||||||
|
|
||||||
|
style: SliderStyle {
|
||||||
|
groove: Item {
|
||||||
|
implicitWidth: 47
|
||||||
|
implicitHeight: 3
|
||||||
|
anchors.centerIn: parent
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
antialiasing: true
|
||||||
|
height: parent.height
|
||||||
|
width: parent.width
|
||||||
|
color: "gray"
|
||||||
|
opacity: 0.8
|
||||||
|
radius: 5
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
antialiasing: true
|
||||||
|
height: parent.height
|
||||||
|
width: parent.width * control.value / control.maximumValue
|
||||||
|
color: "red"
|
||||||
|
radius: 5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
handle: Rectangle {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
color: control.pressed ? "white" : "lightgray"
|
||||||
|
border.color: "gray"
|
||||||
|
border.width: 1
|
||||||
|
implicitWidth: 11
|
||||||
|
implicitHeight: 11
|
||||||
|
radius: 90
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onPressed: {
|
||||||
|
volumebar.visible = !volumebar.visible
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: volumebar
|
||||||
|
hoverEnabled: true
|
||||||
|
propagateComposedEvents: true
|
||||||
|
|
||||||
|
onClicked: mouse.accepted = false;
|
||||||
|
onPressed: mouse.accepted = false;
|
||||||
|
onReleased: mouse.accepted = false;
|
||||||
|
onDoubleClicked: mouse.accepted = false;
|
||||||
|
onPositionChanged: mouse.accepted = false;
|
||||||
|
onPressAndHold: mouse.accepted = false;
|
||||||
|
|
||||||
|
onExited: {
|
||||||
|
volumebar.visible = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: sub
|
||||||
|
font.pointSize: 17
|
||||||
|
font.family: "FontAwesome"
|
||||||
|
text: FontAwesome.Icon.ClosedCaptions
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id : fullscreen
|
||||||
|
font.pointSize: 17
|
||||||
|
font.family: "FontAwesome"
|
||||||
|
text: FontAwesome.Icon.ResizeFull
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
if (window.visibility === Window.FullScreen) {
|
||||||
|
window.showNormal()
|
||||||
|
fullscreen.text = FontAwesome.Icon.ResizeFull
|
||||||
|
} else {
|
||||||
|
window.showFullScreen()
|
||||||
|
fullscreen.text = FontAwesome.Icon.ResizeSmall
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: playbar.width
|
||||||
|
height: 5
|
||||||
|
anchors.bottom: playbar.bottom
|
||||||
|
|
||||||
|
Slider {
|
||||||
|
id: slider
|
||||||
|
maximumValue: player.duration
|
||||||
|
value: player.position
|
||||||
|
onPressedChanged: player.seek(value)
|
||||||
|
enabled: player.mediaInfo.isSeekable
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: sliderMouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
propagateComposedEvents: true
|
||||||
|
|
||||||
|
onClicked: mouse.accepted = false;
|
||||||
|
onPressed: mouse.accepted = false;
|
||||||
|
onReleased: mouse.accepted = false;
|
||||||
|
onDoubleClicked: mouse.accepted = false;
|
||||||
|
onPositionChanged: mouse.accepted = false;
|
||||||
|
onPressAndHold: mouse.accepted = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: hoveredcliptime
|
||||||
|
width: 40
|
||||||
|
height: 17
|
||||||
|
color: "lightgray"
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
visible: sliderMouseArea.containsMouse
|
||||||
|
x: sliderMouseArea.mouseX
|
||||||
|
|
||||||
|
Text {
|
||||||
|
font.pointSize: 13
|
||||||
|
color: "black"
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: {
|
||||||
|
var value = (sliderMouseArea.mouseX - slider.x) * player.duration / (slider.width - slider.x)
|
||||||
|
var date = new Date(Math.floor(value / 1e6));
|
||||||
|
date.getMinutes() + ":" + ('0' + date.getSeconds()).slice(-2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
style: SliderStyle {
|
||||||
|
groove: Item {
|
||||||
|
implicitWidth: playbar.width
|
||||||
|
implicitHeight: 5
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
height: parent.height
|
||||||
|
width: parent.width
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
color: "gray"
|
||||||
|
opacity: 0.8
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
antialiasing: true
|
||||||
|
color: "red"
|
||||||
|
height: parent.height
|
||||||
|
width: parent.width * control.value / control.maximumValue
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
antialiasing: true
|
||||||
|
color: "yellow"
|
||||||
|
height: parent.height
|
||||||
|
width: parent.width * player.buffering / 100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
handle: Rectangle {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
color: control.pressed ? "white" : "lightgray"
|
||||||
|
implicitWidth: 4
|
||||||
|
implicitHeight: 5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
53
playback/player/qt/play.pro
Normal file
53
playback/player/qt/play.pro
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
TEMPLATE = app
|
||||||
|
|
||||||
|
QT += qml quick widgets
|
||||||
|
|
||||||
|
CONFIG += c++11
|
||||||
|
|
||||||
|
DEFINES += GST_USE_UNSTABLE_API
|
||||||
|
|
||||||
|
INCLUDEPATH += ../lib
|
||||||
|
|
||||||
|
RESOURCES += qml.qrc
|
||||||
|
|
||||||
|
# Additional import path used to resolve QML modules in Qt Creator's code model
|
||||||
|
QML_IMPORT_PATH =
|
||||||
|
|
||||||
|
# Default rules for deployment.
|
||||||
|
include(deployment.pri)
|
||||||
|
|
||||||
|
# not tested (yet)
|
||||||
|
unix:!macx {
|
||||||
|
QT_CONFIG -= no-pkg-config
|
||||||
|
CONFIG += link_pkgconfig
|
||||||
|
PKGCONFIG = \
|
||||||
|
gstreamer-1.0 \
|
||||||
|
gstreamer-audio-1.0 \
|
||||||
|
gstreamer-tag-1.0 \
|
||||||
|
gstreamer-pbutils-1.0 \
|
||||||
|
gstreamer-video-1.0 \
|
||||||
|
gstreamer-gl-1.0
|
||||||
|
}
|
||||||
|
|
||||||
|
macx {
|
||||||
|
QMAKE_MAC_SDK = macosx10.9
|
||||||
|
INCLUDEPATH += /Library/Frameworks/GStreamer.framework/Headers
|
||||||
|
|
||||||
|
LIBS += \
|
||||||
|
-framework AppKit \
|
||||||
|
-F/Library/Frameworks -framework GStreamer
|
||||||
|
}
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
qgstplayer.h \
|
||||||
|
player.h \
|
||||||
|
quickrenderer.h
|
||||||
|
|
||||||
|
SOURCES += main.cpp \
|
||||||
|
qgstplayer.cpp \
|
||||||
|
../lib/gst/player/gstplayer.c \
|
||||||
|
../lib/gst/player/gstplayer-media-info.c \
|
||||||
|
player.cpp \
|
||||||
|
quickrenderer.cpp
|
||||||
|
|
||||||
|
DISTFILES +=
|
41
playback/player/qt/player.cpp
Normal file
41
playback/player/qt/player.cpp
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
|
||||||
|
/* GStreamer
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015 Alexandre Moreno <alexmorenocano@gmail.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "player.h"
|
||||||
|
#include "quickrenderer.h"
|
||||||
|
|
||||||
|
Player::Player(QObject *parent)
|
||||||
|
: Player(parent, new QuickRenderer)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Player::Player(QObject *parent, QuickRenderer *renderer)
|
||||||
|
: QGstPlayer(parent, renderer)
|
||||||
|
, renderer_(renderer)
|
||||||
|
{
|
||||||
|
renderer_->setParent(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::setVideoOutput(QQuickItem *output)
|
||||||
|
{
|
||||||
|
renderer_->setVideoItem(output);
|
||||||
|
}
|
44
playback/player/qt/player.h
Normal file
44
playback/player/qt/player.h
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/* GStreamer
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015 Alexandre Moreno <alexmorenocano@gmail.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PLAYER_H
|
||||||
|
#define PLAYER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QQuickItem>
|
||||||
|
#include "qgstplayer.h"
|
||||||
|
|
||||||
|
class QuickRenderer;
|
||||||
|
|
||||||
|
class Player : public QGstPlayer
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
Player(QObject *parent = 0);
|
||||||
|
void setVideoOutput(QQuickItem *output);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Player(QObject *parent, QuickRenderer *renderer);
|
||||||
|
QuickRenderer *renderer_;
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(Player*)
|
||||||
|
|
||||||
|
#endif // PLAYER_H
|
435
playback/player/qt/qgstplayer.cpp
Normal file
435
playback/player/qt/qgstplayer.cpp
Normal file
|
@ -0,0 +1,435 @@
|
||||||
|
/* GStreamer
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015 Alexandre Moreno <alexmorenocano@gmail.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "qgstplayer.h"
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QSize>
|
||||||
|
|
||||||
|
#include <QMetaObject>
|
||||||
|
|
||||||
|
class QGstPlayerRegisterMetaTypes
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QGstPlayerRegisterMetaTypes()
|
||||||
|
{
|
||||||
|
qRegisterMetaType<QGstPlayer::State>("State");
|
||||||
|
}
|
||||||
|
|
||||||
|
} _register;
|
||||||
|
|
||||||
|
QGstPlayer::MediaInfo::MediaInfo(GstPlayerMediaInfo *media_info)
|
||||||
|
: mediaInfo_(media_info)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QGstPlayer::MediaInfo::title() const
|
||||||
|
{
|
||||||
|
QString title = QString::fromLocal8Bit
|
||||||
|
(gst_player_media_info_get_title(mediaInfo_));
|
||||||
|
|
||||||
|
// if media has no title, return the file name
|
||||||
|
if (title.isEmpty()) {
|
||||||
|
QUrl url(gst_player_media_info_get_uri(mediaInfo_));
|
||||||
|
title = url.fileName();
|
||||||
|
}
|
||||||
|
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QGstPlayer::MediaInfo::isSeekable() const
|
||||||
|
{
|
||||||
|
return gst_player_media_info_is_seekable(mediaInfo_);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QGstPlayer::isVideoAvailable() const
|
||||||
|
{
|
||||||
|
GstPlayerVideoInfo *video_info;
|
||||||
|
|
||||||
|
video_info = gst_player_get_current_video_track (player_);
|
||||||
|
if (video_info) {
|
||||||
|
g_object_unref (video_info);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QQmlPropertyMap *QGstPlayer::mediaInfo() const
|
||||||
|
{
|
||||||
|
return mediaInfoMap_;
|
||||||
|
}
|
||||||
|
|
||||||
|
QGstPlayer::QGstPlayer(QObject *parent, QGstPlayer::VideoRenderer *renderer)
|
||||||
|
: QObject(parent)
|
||||||
|
, player_()
|
||||||
|
, state_(STOPPED)
|
||||||
|
, videoDimensions_(QSize())
|
||||||
|
, mediaInfoMap_()
|
||||||
|
, videoAvailable_(false)
|
||||||
|
{
|
||||||
|
|
||||||
|
player_ = gst_player_new_full(renderer ? renderer->renderer() : 0, 0);
|
||||||
|
|
||||||
|
g_object_connect(player_,
|
||||||
|
"swapped-signal::state-changed", G_CALLBACK (QGstPlayer::onStateChanged), this,
|
||||||
|
"swapped-signal::position-updated", G_CALLBACK (QGstPlayer::onPositionUpdated), this,
|
||||||
|
"swapped-signal::duration-changed", G_CALLBACK (QGstPlayer::onDurationChanged), this,
|
||||||
|
"swapped-signal::buffering", G_CALLBACK (QGstPlayer::onBufferingChanged), this,
|
||||||
|
"swapped-signal::video-dimensions-changed", G_CALLBACK (QGstPlayer::onVideoDimensionsChanged), this,
|
||||||
|
"swapped-signal::volume-changed", G_CALLBACK (QGstPlayer::onVolumeChanged), this,
|
||||||
|
"swapped-signal::mute-changed", G_CALLBACK (QGstPlayer::onMuteChanged), this,
|
||||||
|
"swapped-signal::media-info-updated", G_CALLBACK (QGstPlayer::onMediaInfoUpdated), this, NULL);
|
||||||
|
|
||||||
|
mediaInfoMap_ = new QQmlPropertyMap(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
QGstPlayer::onStateChanged(QGstPlayer * player, GstPlayerState state)
|
||||||
|
{
|
||||||
|
player->state_ = static_cast<QGstPlayer::State>(state);
|
||||||
|
|
||||||
|
emit player->stateChanged(player->state_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
QGstPlayer::onPositionUpdated(QGstPlayer * player, GstClockTime position)
|
||||||
|
{
|
||||||
|
emit player->positionChanged(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
QGstPlayer::onDurationChanged(QGstPlayer * player, GstClockTime duration)
|
||||||
|
{
|
||||||
|
emit player->durationChanged(duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
QGstPlayer::onBufferingChanged(QGstPlayer * player, int percent)
|
||||||
|
{
|
||||||
|
emit player->bufferingChanged(percent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
QGstPlayer::onVideoDimensionsChanged(QGstPlayer * player, int w, int h)
|
||||||
|
{
|
||||||
|
QSize res(w,h);
|
||||||
|
|
||||||
|
player->setResolution(res);
|
||||||
|
|
||||||
|
emit player->resolutionChanged(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
QGstPlayer::onVolumeChanged(QGstPlayer *player)
|
||||||
|
{
|
||||||
|
qreal new_val;
|
||||||
|
|
||||||
|
new_val = gst_player_get_volume (player->player_);
|
||||||
|
|
||||||
|
emit player->volumeChanged(new_val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
QGstPlayer::onMuteChanged(QGstPlayer *player)
|
||||||
|
{
|
||||||
|
bool new_val;
|
||||||
|
|
||||||
|
new_val = gst_player_get_mute (player->player_);
|
||||||
|
|
||||||
|
emit player->mutedChanged(new_val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
QGstPlayer::onMediaInfoUpdated(QGstPlayer *player, GstPlayerMediaInfo *media_info)
|
||||||
|
{
|
||||||
|
MediaInfo mediaInfo(media_info);
|
||||||
|
|
||||||
|
player->mediaInfoMap_->insert(QLatin1String("title"),
|
||||||
|
QVariant(mediaInfo.title()));
|
||||||
|
player->mediaInfoMap_->insert(QLatin1String("isSeekable"),
|
||||||
|
QVariant(mediaInfo.isSeekable()));
|
||||||
|
|
||||||
|
bool val = player->isVideoAvailable();
|
||||||
|
|
||||||
|
if (player->videoAvailable_ != val) {
|
||||||
|
player->videoAvailable_ = val;
|
||||||
|
emit player->videoAvailableChanged(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
emit player->mediaInfoChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
QUrl QGstPlayer::source() const
|
||||||
|
{
|
||||||
|
Q_ASSERT(player_ != 0);
|
||||||
|
QString url = QString::fromLocal8Bit(gst_player_get_uri(player_));
|
||||||
|
|
||||||
|
return QUrl(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
qint64 QGstPlayer::duration() const
|
||||||
|
{
|
||||||
|
Q_ASSERT(player_ != 0);
|
||||||
|
|
||||||
|
return gst_player_get_duration(player_);
|
||||||
|
}
|
||||||
|
|
||||||
|
qint64 QGstPlayer::position() const
|
||||||
|
{
|
||||||
|
Q_ASSERT(player_ != 0);
|
||||||
|
|
||||||
|
return gst_player_get_position(player_);
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal QGstPlayer::volume() const
|
||||||
|
{
|
||||||
|
Q_ASSERT(player_ != 0);
|
||||||
|
|
||||||
|
return gst_player_get_volume(player_);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QGstPlayer::isMuted() const
|
||||||
|
{
|
||||||
|
Q_ASSERT(player_ != 0);
|
||||||
|
|
||||||
|
return gst_player_get_mute(player_);
|
||||||
|
}
|
||||||
|
|
||||||
|
int QGstPlayer::buffering() const
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize QGstPlayer::resolution() const
|
||||||
|
{
|
||||||
|
return videoDimensions_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QGstPlayer::setResolution(QSize size)
|
||||||
|
{
|
||||||
|
videoDimensions_ = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
QGstPlayer::State QGstPlayer::state() const
|
||||||
|
{
|
||||||
|
return state_;
|
||||||
|
}
|
||||||
|
|
||||||
|
GstElement *QGstPlayer::pipeline() const
|
||||||
|
{
|
||||||
|
Q_ASSERT(player_ != 0);
|
||||||
|
|
||||||
|
return gst_player_get_pipeline(player_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QGstPlayer::play()
|
||||||
|
{
|
||||||
|
Q_ASSERT(player_ != 0);
|
||||||
|
|
||||||
|
gst_player_play(player_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QGstPlayer::pause()
|
||||||
|
{
|
||||||
|
Q_ASSERT(player_ != 0);
|
||||||
|
|
||||||
|
gst_player_pause(player_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QGstPlayer::stop()
|
||||||
|
{
|
||||||
|
Q_ASSERT(player_ != 0);
|
||||||
|
|
||||||
|
gst_player_stop(player_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QGstPlayer::seek(qint64 position)
|
||||||
|
{
|
||||||
|
Q_ASSERT(player_ != 0);
|
||||||
|
|
||||||
|
gst_player_seek(player_, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QGstPlayer::setSource(QUrl const& url)
|
||||||
|
{
|
||||||
|
Q_ASSERT(player_ != 0);
|
||||||
|
QByteArray uri = url.toString().toLocal8Bit();
|
||||||
|
|
||||||
|
gst_player_set_uri(player_, uri.data());
|
||||||
|
|
||||||
|
emit sourceChanged(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QGstPlayer::setVolume(qreal val)
|
||||||
|
{
|
||||||
|
Q_ASSERT(player_ != 0);
|
||||||
|
|
||||||
|
gst_player_set_volume(player_, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QGstPlayer::setMuted(bool val)
|
||||||
|
{
|
||||||
|
Q_ASSERT(player_ != 0);
|
||||||
|
|
||||||
|
gst_player_set_mute(player_, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QGstPlayer::setPosition(qint64 pos)
|
||||||
|
{
|
||||||
|
Q_ASSERT(player_ != 0);
|
||||||
|
|
||||||
|
gst_player_seek(player_, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
GstPlayerVideoRenderer *QGstPlayer::VideoRenderer::renderer()
|
||||||
|
{
|
||||||
|
return renderer_;
|
||||||
|
}
|
||||||
|
|
||||||
|
QGstPlayer::VideoRenderer::VideoRenderer()
|
||||||
|
{
|
||||||
|
renderer_ = static_cast<GstPlayerVideoRenderer*>
|
||||||
|
(g_object_new (GST_TYPE_PLAYER_QT_VIDEO_RENDERER, "renderer", this, NULL));
|
||||||
|
}
|
||||||
|
|
||||||
|
QGstPlayer::VideoRenderer::~VideoRenderer()
|
||||||
|
{
|
||||||
|
if (renderer_) gst_object_unref(renderer_);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct _GstPlayerQtVideoRenderer
|
||||||
|
{
|
||||||
|
GObject parent;
|
||||||
|
|
||||||
|
gpointer renderer;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _GstPlayerQtVideoRendererClass
|
||||||
|
{
|
||||||
|
GObjectClass parent_class;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_player_qt_video_renderer_interface_init
|
||||||
|
(GstPlayerVideoRendererInterface * iface);
|
||||||
|
|
||||||
|
G_DEFINE_TYPE_WITH_CODE (GstPlayerQtVideoRenderer,
|
||||||
|
gst_player_qt_video_renderer, G_TYPE_OBJECT,
|
||||||
|
G_IMPLEMENT_INTERFACE (GST_TYPE_PLAYER_VIDEO_RENDERER,
|
||||||
|
gst_player_qt_video_renderer_interface_init))
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
QT_VIDEO_RENDERER_PROP_0,
|
||||||
|
QT_VIDEO_RENDERER_PROP_RENDERER,
|
||||||
|
QT_VIDEO_RENDERER_PROP_LAST
|
||||||
|
};
|
||||||
|
|
||||||
|
static GParamSpec * qt_video_renderer_param_specs
|
||||||
|
[QT_VIDEO_RENDERER_PROP_LAST] = { NULL, };
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_player_qt_video_renderer_set_property (GObject * object,
|
||||||
|
guint prop_id, const GValue * value, GParamSpec * pspec)
|
||||||
|
{
|
||||||
|
GstPlayerQtVideoRenderer *self = GST_PLAYER_QT_VIDEO_RENDERER (object);
|
||||||
|
|
||||||
|
switch (prop_id) {
|
||||||
|
case QT_VIDEO_RENDERER_PROP_RENDERER:
|
||||||
|
qDebug() << "setting renderer";
|
||||||
|
self->renderer = g_value_get_pointer (value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_player_qt_video_renderer_get_property (GObject * object,
|
||||||
|
guint prop_id, GValue * value, GParamSpec * pspec)
|
||||||
|
{
|
||||||
|
GstPlayerQtVideoRenderer *self = GST_PLAYER_QT_VIDEO_RENDERER (object);
|
||||||
|
|
||||||
|
switch (prop_id) {
|
||||||
|
case QT_VIDEO_RENDERER_PROP_RENDERER:
|
||||||
|
g_value_set_pointer (value, self->renderer);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_player_qt_video_renderer_finalize (GObject * object)
|
||||||
|
{
|
||||||
|
GstPlayerQtVideoRenderer *self = GST_PLAYER_QT_VIDEO_RENDERER (object);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS
|
||||||
|
(gst_player_qt_video_renderer_parent_class)->finalize(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_player_qt_video_renderer_class_init
|
||||||
|
(GstPlayerQtVideoRendererClass * klass)
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
gobject_class->set_property =
|
||||||
|
gst_player_qt_video_renderer_set_property;
|
||||||
|
gobject_class->get_property =
|
||||||
|
gst_player_qt_video_renderer_get_property;
|
||||||
|
gobject_class->finalize = gst_player_qt_video_renderer_finalize;
|
||||||
|
|
||||||
|
qt_video_renderer_param_specs
|
||||||
|
[QT_VIDEO_RENDERER_PROP_RENDERER] =
|
||||||
|
g_param_spec_pointer ("renderer", "Qt Renderer", "",
|
||||||
|
static_cast<GParamFlags>(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
|
g_object_class_install_properties (gobject_class,
|
||||||
|
QT_VIDEO_RENDERER_PROP_LAST,
|
||||||
|
qt_video_renderer_param_specs);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_player_qt_video_renderer_init (GstPlayerQtVideoRenderer * self)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstElement *
|
||||||
|
gst_player_qt_video_renderer_create_video_sink
|
||||||
|
(GstPlayerVideoRenderer * iface, GstPlayer *player)
|
||||||
|
{
|
||||||
|
GstPlayerQtVideoRenderer *self = GST_PLAYER_QT_VIDEO_RENDERER (iface);
|
||||||
|
|
||||||
|
g_assert(self->renderer != NULL);
|
||||||
|
|
||||||
|
return static_cast<QGstPlayer::VideoRenderer*>(self->renderer)->createVideoSink();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_player_qt_video_renderer_interface_init
|
||||||
|
(GstPlayerVideoRendererInterface * iface)
|
||||||
|
{
|
||||||
|
iface->create_video_sink = gst_player_qt_video_renderer_create_video_sink;
|
||||||
|
}
|
162
playback/player/qt/qgstplayer.h
Normal file
162
playback/player/qt/qgstplayer.h
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
/* GStreamer
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015 Alexandre Moreno <alexmorenocano@gmail.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef QGSTPLAYER_H
|
||||||
|
#define QGSTPLAYER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QUrl>
|
||||||
|
#include <QSize>
|
||||||
|
//#include <QtGui/qwindowdefs.h>
|
||||||
|
#include <QtQml/QQmlPropertyMap>
|
||||||
|
#include <gst/player/player.h>
|
||||||
|
|
||||||
|
class QGstPlayer : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
|
||||||
|
Q_PROPERTY(qint64 duration READ duration NOTIFY durationChanged)
|
||||||
|
Q_PROPERTY(qint64 position READ position NOTIFY positionChanged)
|
||||||
|
Q_PROPERTY(qreal volume READ volume WRITE setVolume NOTIFY volumeChanged)
|
||||||
|
Q_PROPERTY(bool muted READ isMuted WRITE setMuted NOTIFY mutedChanged)
|
||||||
|
Q_PROPERTY(int buffering READ buffering NOTIFY bufferingChanged)
|
||||||
|
Q_PROPERTY(QSize resolution READ resolution WRITE setResolution NOTIFY resolutionChanged)
|
||||||
|
Q_PROPERTY(State state READ state NOTIFY stateChanged)
|
||||||
|
Q_PROPERTY(QObject *mediaInfo READ mediaInfo NOTIFY mediaInfoChanged)
|
||||||
|
Q_PROPERTY(bool videoAvailable READ isVideoAvailable NOTIFY videoAvailableChanged)
|
||||||
|
|
||||||
|
Q_ENUMS(State)
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
class VideoRenderer;
|
||||||
|
|
||||||
|
explicit QGstPlayer(QObject *parent = 0, VideoRenderer *renderer = 0);
|
||||||
|
|
||||||
|
typedef GstPlayerError Error;
|
||||||
|
enum State {
|
||||||
|
STOPPED = GST_PLAYER_STATE_STOPPED,
|
||||||
|
BUFFERING = GST_PLAYER_STATE_BUFFERING,
|
||||||
|
PAUSED = GST_PLAYER_STATE_PAUSED,
|
||||||
|
PLAYING = GST_PLAYER_STATE_PLAYING
|
||||||
|
};
|
||||||
|
|
||||||
|
class VideoRenderer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GstPlayerVideoRenderer *renderer();
|
||||||
|
virtual GstElement *createVideoSink() = 0;
|
||||||
|
protected:
|
||||||
|
VideoRenderer();
|
||||||
|
virtual ~VideoRenderer();
|
||||||
|
private:
|
||||||
|
GstPlayerVideoRenderer *renderer_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO add remaining bits
|
||||||
|
class MediaInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MediaInfo(GstPlayerMediaInfo *media_info);
|
||||||
|
QString title() const;
|
||||||
|
bool isSeekable() const;
|
||||||
|
private:
|
||||||
|
GstPlayerMediaInfo *mediaInfo_;
|
||||||
|
};
|
||||||
|
|
||||||
|
QUrl source() const;
|
||||||
|
qint64 duration() const;
|
||||||
|
qint64 position() const;
|
||||||
|
qreal volume() const;
|
||||||
|
bool isMuted() const;
|
||||||
|
int buffering() const;
|
||||||
|
State state() const;
|
||||||
|
GstElement *pipeline() const;
|
||||||
|
QSize resolution() const;
|
||||||
|
void setResolution(QSize size);
|
||||||
|
bool isVideoAvailable() const;
|
||||||
|
QQmlPropertyMap *mediaInfo() const;
|
||||||
|
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void stateChanged(State new_state);
|
||||||
|
void bufferingChanged(int percent);
|
||||||
|
void enfOfStream();
|
||||||
|
void positionChanged(qint64 new_position);
|
||||||
|
void durationChanged(qint64 duration);
|
||||||
|
void resolutionChanged(QSize resolution);
|
||||||
|
void volumeChanged(qreal volume);
|
||||||
|
void mutedChanged(bool muted);
|
||||||
|
void mediaInfoChanged();
|
||||||
|
void sourceChanged(QUrl new_url);
|
||||||
|
void videoAvailableChanged(bool videoAvailable);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void play();
|
||||||
|
void pause();
|
||||||
|
void stop();
|
||||||
|
void seek(qint64 position);
|
||||||
|
void setSource(QUrl const& url);
|
||||||
|
void setVolume(qreal val);
|
||||||
|
void setMuted(bool val);
|
||||||
|
void setPosition(qint64 pos);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Q_DISABLE_COPY(QGstPlayer)
|
||||||
|
static void onStateChanged(QGstPlayer *, GstPlayerState state);
|
||||||
|
static void onPositionUpdated(QGstPlayer *, GstClockTime position);
|
||||||
|
static void onDurationChanged(QGstPlayer *, GstClockTime duration);
|
||||||
|
static void onBufferingChanged(QGstPlayer *, int percent);
|
||||||
|
static void onVideoDimensionsChanged(QGstPlayer *, int w, int h);
|
||||||
|
static void onVolumeChanged(QGstPlayer *);
|
||||||
|
static void onMuteChanged(QGstPlayer *);
|
||||||
|
static void onMediaInfoUpdated(QGstPlayer *, GstPlayerMediaInfo *media_info);
|
||||||
|
|
||||||
|
GstPlayer *player_;
|
||||||
|
State state_;
|
||||||
|
QSize videoDimensions_;
|
||||||
|
QQmlPropertyMap *mediaInfoMap_;
|
||||||
|
bool videoAvailable_;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
typedef struct _GstPlayerQtVideoRenderer
|
||||||
|
GstPlayerQtVideoRenderer;
|
||||||
|
|
||||||
|
typedef struct _GstPlayerQtVideoRendererClass
|
||||||
|
GstPlayerQtVideoRendererClass;
|
||||||
|
|
||||||
|
#define GST_TYPE_PLAYER_QT_VIDEO_RENDERER (gst_player_qt_video_renderer_get_type ())
|
||||||
|
#define GST_IS_PLAYER_QT_VIDEO_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_PLAYER_QT_VIDEO_RENDERER))
|
||||||
|
#define GST_IS_PLAYER_QT_VIDEO_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_PLAYER_QT_VIDEO_RENDERER))
|
||||||
|
#define GST_PLAYER_QT_VIDEO_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_PLAYER_QT_VIDEO_RENDERER, GstPlayerQtVideoRendererClass))
|
||||||
|
#define GST_PLAYER_QT_VIDEO_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_PLAYER_QT_VIDEO_RENDERER, GstPlayerQtVideoRenderer))
|
||||||
|
#define GST_PLAYER_QT_VIDEO_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_PLAYER_QT_VIDEO_RENDERER, GstPlayerQtVideoRendererClass))
|
||||||
|
#define GST_PLAYER_QT_VIDEO_RENDERER_CAST(obj) ((GstPlayerQtVideoRenderer*)(obj))
|
||||||
|
|
||||||
|
GType gst_player_qt_video_renderer_get_type (void);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(QGstPlayer*)
|
||||||
|
Q_DECLARE_METATYPE(QGstPlayer::State)
|
||||||
|
|
||||||
|
#endif // QGSTPLAYER_H
|
9
playback/player/qt/qml.qrc
Normal file
9
playback/player/qt/qml.qrc
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<RCC>
|
||||||
|
<qresource prefix="/">
|
||||||
|
<file>main.qml</file>
|
||||||
|
<file>fontawesome.js</file>
|
||||||
|
</qresource>
|
||||||
|
<qresource prefix="/fonts">
|
||||||
|
<file>fontawesome-webfont.ttf</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
56
playback/player/qt/quickrenderer.cpp
Normal file
56
playback/player/qt/quickrenderer.cpp
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
/* GStreamer
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015 Alexandre Moreno <alexmorenocano@gmail.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "quickrenderer.h"
|
||||||
|
|
||||||
|
QuickRenderer::QuickRenderer(QObject *parent)
|
||||||
|
: QObject(parent)
|
||||||
|
, QGstPlayer::VideoRenderer()
|
||||||
|
, sink()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QuickRenderer::~QuickRenderer()
|
||||||
|
{
|
||||||
|
if (sink) gst_object_unref(sink);
|
||||||
|
}
|
||||||
|
|
||||||
|
GstElement *QuickRenderer::createVideoSink()
|
||||||
|
{
|
||||||
|
GstElement *qmlglsink = gst_element_factory_make("qmlglsink", NULL);
|
||||||
|
|
||||||
|
GstElement *glsinkbin = gst_element_factory_make ("glsinkbin", NULL);
|
||||||
|
|
||||||
|
Q_ASSERT(qmlglsink && glsinkbin);
|
||||||
|
|
||||||
|
g_object_set (glsinkbin, "sink", qmlglsink, NULL);
|
||||||
|
|
||||||
|
sink = static_cast<GstElement*>(gst_object_ref_sink(qmlglsink));
|
||||||
|
|
||||||
|
return glsinkbin;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QuickRenderer::setVideoItem(QQuickItem *item)
|
||||||
|
{
|
||||||
|
Q_ASSERT(item);
|
||||||
|
|
||||||
|
g_object_set(sink, "widget", item, NULL);
|
||||||
|
}
|
42
playback/player/qt/quickrenderer.h
Normal file
42
playback/player/qt/quickrenderer.h
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
/* GStreamer
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015 Alexandre Moreno <alexmorenocano@gmail.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef QUICKPLAYER_H
|
||||||
|
#define QUICKPLAYER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QQuickItem>
|
||||||
|
#include "qgstplayer.h"
|
||||||
|
|
||||||
|
class QuickRenderer : public QObject, public QGstPlayer::VideoRenderer
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
QuickRenderer(QObject *parent = 0);
|
||||||
|
~QuickRenderer();
|
||||||
|
|
||||||
|
GstElement *createVideoSink();
|
||||||
|
void setVideoItem(QQuickItem *item);
|
||||||
|
|
||||||
|
private:
|
||||||
|
GstElement *sink;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QUICKPLAYER_H
|
Loading…
Reference in a new issue