mirror of
https://github.com/HenkKalkwater/harbour-sailfin.git
synced 2024-11-22 09:15:18 +00:00
Add track selection back
This commit is contained in:
parent
5a24bdee59
commit
1aae311b9b
|
@ -17,6 +17,7 @@ set(JellyfinQt_SOURCES
|
|||
src/viewmodel/item.cpp
|
||||
src/viewmodel/itemmodel.cpp
|
||||
src/viewmodel/loader.cpp
|
||||
src/viewmodel/mediastream.cpp
|
||||
src/viewmodel/modelstatus.cpp
|
||||
src/viewmodel/playbackmanager.cpp
|
||||
src/viewmodel/playlist.cpp
|
||||
|
@ -47,6 +48,7 @@ set(JellyfinQt_HEADERS
|
|||
include/JellyfinQt/viewmodel/item.h
|
||||
include/JellyfinQt/viewmodel/itemmodel.h
|
||||
include/JellyfinQt/viewmodel/loader.h
|
||||
include/JellyfinQt/viewmodel/mediastream.h
|
||||
include/JellyfinQt/viewmodel/modelstatus.h
|
||||
include/JellyfinQt/viewmodel/propertyhelper.h
|
||||
include/JellyfinQt/viewmodel/playbackmanager.h
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "../loader/http/getitem.h"
|
||||
#include "../loader/requesttypes.h"
|
||||
#include "../model/item.h"
|
||||
#include "mediastream.h"
|
||||
#include "loader.h"
|
||||
|
||||
namespace Jellyfin {
|
||||
|
@ -109,8 +110,11 @@ public:
|
|||
Q_PROPERTY(QString seriesId READ seriesId NOTIFY seriesIdChanged)
|
||||
Q_PROPERTY(QString seasonId READ seasonId NOTIFY seasonIdChanged)
|
||||
Q_PROPERTY(QString seasonName READ seasonName NOTIFY seasonNameChanged)
|
||||
/*Q_PROPERTY(QList<MediaStream *> __list__mediaStreams MEMBER __list__m_mediaStreams NOTIFY mediaStreamsChanged)
|
||||
Q_PROPERTY(QVariantList mediaStreams READ mediaStreams NOTIFY mediaStreamsChanged STORED false)*/
|
||||
/*Q_PROPERTY(QList<MediaStream *> __list__mediaStreams MEMBER __list__m_mediaStreams NOTIFY mediaStreamsChanged)*/
|
||||
Q_PROPERTY(QList<QObject *> mediaStreams READ mediaStreams NOTIFY mediaStreamsChanged)
|
||||
Q_PROPERTY(QList<QObject *> audioStreams READ audioStreams NOTIFY audioStreamsChanged)
|
||||
Q_PROPERTY(QList<QObject *> videoStreams READ videoStreams NOTIFY videoStreamsChanged)
|
||||
Q_PROPERTY(QList<QObject *> subtitleStreams READ subtitleStreams NOTIFY subtitleStreamsChanged)
|
||||
Q_PROPERTY(QStringList artists READ artists NOTIFY artistsChanged)
|
||||
// Why is this a QJsonObject? Well, because I couldn't be bothered to implement the deserialisations of
|
||||
// a QHash at the moment.
|
||||
|
@ -152,6 +156,10 @@ public:
|
|||
QString seasonId() const { return m_data->seasonId(); }
|
||||
QString seasonName() const { return m_data->seasonName(); }
|
||||
|
||||
QObjectList mediaStreams() const { return m_allMediaStreams; }
|
||||
QObjectList audioStreams() const { return m_audioStreams; }
|
||||
QObjectList videoStreams() const { return m_videoStreams; }
|
||||
QObjectList subtitleStreams() const { return m_subtitleStreams; }
|
||||
QStringList artists() const { return m_data->artists(); }
|
||||
QJsonObject imageTags() const { return m_data->imageTags(); }
|
||||
QStringList backdropImageTags() const { return m_data->backdropImageTags(); }
|
||||
|
@ -208,7 +216,10 @@ signals:
|
|||
void seriesIdChanged(const QString &newSeriesId);
|
||||
void seasonIdChanged(const QString &newSeasonId);
|
||||
void seasonNameChanged(const QString &newSeasonName);
|
||||
void mediaStreamsChanged(/*const QList<MediaStream *> &newMediaStreams*/);
|
||||
void mediaStreamsChanged(QVariantList &newMediaStreams);
|
||||
void audioStreamsChanged(QVariantList &newAudioStreams);
|
||||
void videoStreamsChanged(QVariantList &newVideoStreams);
|
||||
void subtitleStreamsChanged(QVariantList &newSubtitleStreams);
|
||||
void artistsChanged(const QStringList &newArtists);
|
||||
void imageTagsChanged();
|
||||
void backdropImageTagsChanged();
|
||||
|
@ -219,9 +230,14 @@ signals:
|
|||
protected:
|
||||
void setUserData(DTO::UserItemDataDto &newData);
|
||||
void setUserData(QSharedPointer<DTO::UserItemDataDto> newData);
|
||||
void updateMediaStreams();
|
||||
|
||||
QSharedPointer<Model::Item> m_data;
|
||||
UserData *m_userData = nullptr;
|
||||
QObjectList m_allMediaStreams;
|
||||
QObjectList m_audioStreams;
|
||||
QObjectList m_videoStreams;
|
||||
QObjectList m_subtitleStreams;
|
||||
private slots:
|
||||
void onUserDataChanged(const DTO::UserItemDataDto &userData);
|
||||
};
|
||||
|
|
|
@ -34,7 +34,17 @@
|
|||
#include "propertyhelper.h"
|
||||
|
||||
// Jellyfin Forward Read/Write Property
|
||||
#define FWDPROP(type, propName, propSetName) JF_FWD_RW_PROP(type, propName, propSetName, this->m_parameters)
|
||||
#define FWDPROP(type, propName, propSetName) \
|
||||
public: \
|
||||
Q_PROPERTY(type propName READ propName WRITE set##propSetName NOTIFY propName##Changed) \
|
||||
type propName() const { return this->m_parameters.propName(); } \
|
||||
void set##propSetName(type newValue) { \
|
||||
this->m_parameters.set##propSetName( newValue ); \
|
||||
emit propName##Changed(); \
|
||||
autoReloadIfNeeded(); \
|
||||
} \
|
||||
Q_SIGNALS: \
|
||||
void propName##Changed();
|
||||
|
||||
namespace Jellyfin {
|
||||
|
||||
|
@ -161,6 +171,7 @@ public:
|
|||
FWDPROP(bool, isPlaceHolder, IsPlaceHolder)
|
||||
FWDPROP(bool, isPlayed, IsPlayed)
|
||||
FWDPROP(bool, isUnaired, IsUnaired)
|
||||
FWDPROP(int, limit, Limit)
|
||||
FWDPROP(QList<Jellyfin::DTO::LocationTypeClass::Value>, locationTypes, LocationTypes)
|
||||
FWDPROP(qint32, maxHeight, MaxHeight)
|
||||
FWDPROP(QString, maxOfficialRating, MaxOfficialRating)
|
||||
|
|
|
@ -185,17 +185,22 @@ private:
|
|||
* @brief Updates the data when finished.
|
||||
*/
|
||||
void onLoaderReady() {
|
||||
R newData = m_loader->result();
|
||||
if (m_dataViewModel->data()->sameAs(newData)) {
|
||||
// Replace the data the model holds
|
||||
m_dataViewModel->data()->replaceData(newData);
|
||||
} else {
|
||||
// Replace the model
|
||||
using PointerType = typename decltype(m_dataViewModel->data())::Type;
|
||||
m_dataViewModel = new T(this, QSharedPointer<PointerType>::create(newData, m_apiClient));
|
||||
try {
|
||||
R newData = m_loader->result();
|
||||
if (m_dataViewModel->data()->sameAs(newData)) {
|
||||
// Replace the data the model holds
|
||||
m_dataViewModel->data()->replaceData(newData);
|
||||
} else {
|
||||
// Replace the model
|
||||
using PointerType = typename decltype(m_dataViewModel->data())::Type;
|
||||
m_dataViewModel = new T(this, QSharedPointer<PointerType>::create(newData, m_apiClient));
|
||||
}
|
||||
setStatus(Ready);
|
||||
emitDataChanged();
|
||||
} catch(QException &e) {
|
||||
setErrorString(e.what());
|
||||
setStatus(Error);
|
||||
}
|
||||
setStatus(Ready);
|
||||
emitDataChanged();
|
||||
}
|
||||
|
||||
void onLoaderError(QString message) {
|
||||
|
|
153
core/include/JellyfinQt/viewmodel/mediastream.h
Normal file
153
core/include/JellyfinQt/viewmodel/mediastream.h
Normal file
|
@ -0,0 +1,153 @@
|
|||
/* * Sailfin: a Jellyfin client written using Qt
|
||||
* Copyright (C) 2021 Chris Josten and the Sailfin Contributors.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#ifndef JELLYFIN_VIEWMODEL_MEDIASTREAM_H
|
||||
#define JELLYFIN_VIEWMODEL_MEDIASTREAM_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QScopedPointer>
|
||||
|
||||
#include "../dto/mediastream.h"
|
||||
|
||||
namespace Jellyfin {
|
||||
namespace ViewModel {
|
||||
|
||||
class MediaStream : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MediaStream(QSharedPointer<DTO::MediaStream> data, QObject *parent = nullptr);
|
||||
|
||||
Q_PROPERTY(QString codec READ codec NOTIFY codecChanged)
|
||||
Q_PROPERTY(QString codecTag READ codecTag NOTIFY codecTagChanged)
|
||||
Q_PROPERTY(QString language READ language NOTIFY languageChanged)
|
||||
Q_PROPERTY(QString colorRange READ colorRange NOTIFY colorRangeChanged)
|
||||
Q_PROPERTY(QString colorSpace READ colorSpace NOTIFY colorSpaceChanged)
|
||||
Q_PROPERTY(QString colorTransfer READ colorTransfer NOTIFY colorTransferChanged)
|
||||
Q_PROPERTY(QString colorPrimaries READ colorPrimaries NOTIFY colorPrimariesChanged)
|
||||
Q_PROPERTY(QString comment READ comment NOTIFY commentChanged);
|
||||
Q_PROPERTY(QString timeBase READ timeBase NOTIFY timeBaseChanged);
|
||||
Q_PROPERTY(QString title READ title NOTIFY titleChanged);
|
||||
Q_PROPERTY(QString videoRange READ videoRange NOTIFY videoRangeChanged);
|
||||
Q_PROPERTY(QString localizedUndefined READ localizedUndefined NOTIFY localizedUndefinedChanged);
|
||||
Q_PROPERTY(QString localizedDefault READ localizedDefault NOTIFY localizedDefaultChanged);
|
||||
Q_PROPERTY(QString localizedForced READ localizedForced NOTIFY localizedForcedChanged);
|
||||
Q_PROPERTY(QString displayTitle READ displayTitle NOTIFY displayTitleChanged);
|
||||
Q_PROPERTY(QString nalLengthSize READ nalLengthSize NOTIFY nalLengthSizeChanged);
|
||||
Q_PROPERTY(bool interlaced READ interlaced NOTIFY interlacedChanged)
|
||||
Q_PROPERTY(bool avc READ avc NOTIFY avcChanged)
|
||||
Q_PROPERTY(QString channelLayout READ channelLayout NOTIFY channelLayoutChanged)
|
||||
Q_PROPERTY(qint32 bitRate READ bitRate NOTIFY bitRateChanged)
|
||||
Q_PROPERTY(qint32 bitDepth READ bitDepth NOTIFY bitDepthChanged)
|
||||
Q_PROPERTY(qint32 refFrames READ refFrames NOTIFY refFramesChanged)
|
||||
Q_PROPERTY(qint32 packetLength READ packetLength NOTIFY packetLengthChanged)
|
||||
Q_PROPERTY(qint32 channels READ channels NOTIFY channelsChanged)
|
||||
Q_PROPERTY(qint32 sampleRate READ sampleRate NOTIFY sampleRateChanged)
|
||||
Q_PROPERTY(bool isDefault READ isDefault NOTIFY isDefaultChanged)
|
||||
Q_PROPERTY(bool forced READ forced NOTIFY forcedChanged)
|
||||
Q_PROPERTY(qint32 width READ width NOTIFY widthChanged)
|
||||
Q_PROPERTY(qint32 height READ height NOTIFY heightChanged)
|
||||
Q_PROPERTY(float averageFrameRate READ averageFrameRate NOTIFY averageFrameRateChanged)
|
||||
Q_PROPERTY(float realFrameRate READ realFrameRate NOTIFY realFrameRateChanged)
|
||||
Q_PROPERTY(QString profile READ profile NOTIFY profileChanged)
|
||||
Q_PROPERTY(Jellyfin::DTO::MediaStreamTypeClass::Value type READ type NOTIFY typeChanged)
|
||||
Q_PROPERTY(QString aspectRatio READ aspectRatio NOTIFY aspectRatioChanged)
|
||||
Q_PROPERTY(qint32 index READ index NOTIFY indexChanged)
|
||||
|
||||
|
||||
QString codec() const { return m_data->codec(); }
|
||||
QString codecTag() const { return m_data->codecTag(); }
|
||||
QString language() const { return m_data->language(); }
|
||||
QString colorRange() const { return m_data->colorRange(); }
|
||||
QString colorSpace() const { return m_data->colorSpace(); }
|
||||
QString colorTransfer() const { return m_data->colorTransfer(); }
|
||||
QString colorPrimaries() const { return m_data->colorPrimaries(); }
|
||||
QString comment() const { return m_data->comment(); }
|
||||
QString timeBase() const { return m_data->timeBase(); }
|
||||
QString title() const { return m_data->title(); }
|
||||
QString videoRange() const { return m_data->videoRange(); }
|
||||
QString localizedUndefined() const { return m_data->localizedUndefined(); }
|
||||
QString localizedDefault() const { return m_data->localizedDefault(); }
|
||||
QString localizedForced() const { return m_data->localizedForced(); }
|
||||
QString displayTitle() const { return m_data->displayTitle(); }
|
||||
QString nalLengthSize() const { return m_data->nalLengthSize(); }
|
||||
bool interlaced() const { return m_data->isInterlaced(); }
|
||||
bool avc() const { return m_data->isAVC().value_or(false); }
|
||||
QString channelLayout() const { return m_data->channelLayout(); }
|
||||
qint32 bitRate() const { return m_data->bitRate().value_or(-1); }
|
||||
qint32 bitDepth() const { return m_data->bitDepth().value_or(-1); }
|
||||
qint32 refFrames() const { return m_data->refFrames().value_or(-1); }
|
||||
qint32 packetLength() const { return m_data->packetLength().value_or(-1); }
|
||||
qint32 channels() const { return m_data->channels().value_or(-1); }
|
||||
qint32 sampleRate() const { return m_data->sampleRate().value_or(-1); }
|
||||
bool isDefault() const { return m_data->isDefault(); }
|
||||
bool forced() const { return m_data->isForced(); }
|
||||
qint32 width() const { return m_data->width().value_or(-1); }
|
||||
qint32 height() const { return m_data->height().value_or(-1); }
|
||||
float averageFrameRate() const { return m_data->averageFrameRate().value_or(-1.0); }
|
||||
float realFrameRate() const { return m_data->realFrameRate().value_or(-1.0); }
|
||||
QString profile() const { return m_data->profile(); }
|
||||
DTO::MediaStreamType type() const { return m_data->type(); }
|
||||
QString aspectRatio() const { return m_data->aspectRatio(); }
|
||||
qint32 index() const { return m_data->index(); }
|
||||
|
||||
|
||||
signals:
|
||||
void codecChanged(const QString &newCodec);
|
||||
void codecTagChanged(const QString &newCodecTag);
|
||||
void languageChanged(const QString &newLanguage);
|
||||
void colorRangeChanged(const QString &newColorRange);
|
||||
void colorSpaceChanged(const QString &newColorSpace);
|
||||
void colorTransferChanged(const QString &newColorTransfer);
|
||||
void colorPrimariesChanged(const QString &newColorPrimaries);
|
||||
void commentChanged(const QString &newComment);
|
||||
void timeBaseChanged(const QString &newTimeBase);
|
||||
void titleChanged(const QString &newTitle);
|
||||
void videoRangeChanged(const QString &newVideoRanged);
|
||||
void localizedUndefinedChanged(const QString &newLocalizedUndefined);
|
||||
void localizedDefaultChanged(const QString &newLocalizedDefault);
|
||||
void localizedForcedChanged(const QString &newLocalizedForced);
|
||||
void displayTitleChanged(const QString &newDisplayTitle);
|
||||
void nalLengthSizeChanged(const QString &newNalLengthSize);
|
||||
void interlacedChanged(bool newInterlaced);
|
||||
void avcChanged(bool newAVC);
|
||||
void channelLayoutChanged(const QString &newChannelLayout);
|
||||
void bitRateChanged(qint32 newBitRate);
|
||||
void bitDepthChanged(qint32 newBitDepth);
|
||||
void refFramesChanged(qint32 newRefFrames);
|
||||
void packetLengthChanged(qint32 newPacketLength);
|
||||
void channelsChanged(qint32 newChannels);
|
||||
void sampleRateChanged(qint32 newSampleRate);
|
||||
void isDefaultChanged(bool newIsDefault);
|
||||
void forcedChanged(bool newForced);
|
||||
void heightChanged(qint32 newHeight);
|
||||
void widthChanged(qint32 newWidth);
|
||||
void averageFrameRateChanged(float newAverageFrameRate);
|
||||
void realFrameRateChanged(float newRealFrameRate);
|
||||
void profileChanged(const QString &newProfile);
|
||||
void typeChanged(const Jellyfin::DTO::MediaStreamTypeClass::Value newType);
|
||||
void aspectRatioChanged(const QString &newAspectRatio);
|
||||
void indexChanged(qint32 newIndex);
|
||||
|
||||
private:
|
||||
QSharedPointer<DTO::MediaStream> m_data;
|
||||
};
|
||||
|
||||
|
||||
} // ViewModel
|
||||
} // Jellyfin
|
||||
|
||||
#endif // JELLYFIN_VIEWMODEL_MEDIASTREAM_H
|
|
@ -28,6 +28,7 @@ Item::Item(QObject *parent, QSharedPointer<Model::Item> data)
|
|||
m_userData(new UserData(this)){
|
||||
connect(m_data.data(), &Model::Item::userDataChanged, this, &Item::onUserDataChanged);
|
||||
m_userData->setData(data->userData());
|
||||
updateMediaStreams();
|
||||
}
|
||||
|
||||
void Item::setData(QSharedPointer<Model::Item> newData) {
|
||||
|
@ -41,9 +42,39 @@ void Item::setData(QSharedPointer<Model::Item> newData) {
|
|||
connect(m_data.data(), &Model::Item::userDataChanged, this, &Item::onUserDataChanged);
|
||||
setUserData(m_data->userData());
|
||||
}
|
||||
|
||||
emit userDataChanged(m_userData);
|
||||
}
|
||||
|
||||
void Item::updateMediaStreams() {
|
||||
m_allMediaStreams.clear();
|
||||
m_audioStreams.clear();
|
||||
m_videoStreams.clear();
|
||||
m_subtitleStreams.clear();
|
||||
const QList<DTO::MediaStream> streams = m_data->mediaStreams();
|
||||
for (auto it = streams.cbegin(); it != streams.cend(); it++) {
|
||||
MediaStream *stream = new MediaStream(QSharedPointer<DTO::MediaStream>::create(*it), this);
|
||||
|
||||
m_allMediaStreams.append(stream);
|
||||
switch(stream->type()) {
|
||||
case DTO::MediaStreamType::Audio:
|
||||
m_audioStreams.append(stream);
|
||||
break;
|
||||
case DTO::MediaStreamType::Video:
|
||||
m_videoStreams.append(stream);
|
||||
break;
|
||||
case DTO::MediaStreamType::Subtitle:
|
||||
m_subtitleStreams.append(stream);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
qDebug() << m_audioStreams.size() << " audio streams, " << m_videoStreams.size() << " video streams, "
|
||||
<< m_subtitleStreams.size() << " subtitle streams, " << m_allMediaStreams.size() << " streams total";
|
||||
|
||||
}
|
||||
|
||||
void Item::setUserData(DTO::UserItemDataDto &newData) {
|
||||
setUserData(QSharedPointer<DTO::UserItemDataDto>::create(newData));
|
||||
}
|
||||
|
|
30
core/src/viewmodel/mediastream.cpp
Normal file
30
core/src/viewmodel/mediastream.cpp
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Sailfin: a Jellyfin client written using Qt
|
||||
* Copyright (C) 2021 Chris Josten and the Sailfin Contributors.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "JellyfinQt/viewmodel/mediastream.h"
|
||||
|
||||
namespace Jellyfin {
|
||||
namespace ViewModel {
|
||||
|
||||
MediaStream::MediaStream(QSharedPointer<DTO::MediaStream> data, QObject *parent)
|
||||
: QObject(parent),
|
||||
m_data(data) {}
|
||||
|
||||
}
|
||||
}
|
|
@ -286,6 +286,8 @@ void PlaybackManager::requestItemUrl(QSharedPointer<Model::Item> item) {
|
|||
params.setEnableDirectPlay(true);
|
||||
params.setEnableDirectStream(true);
|
||||
params.setEnableTranscoding(true);
|
||||
params.setAudioStreamIndex(this->m_audioIndex);
|
||||
params.setSubtitleStreamIndex(this->m_subtitleIndex);
|
||||
|
||||
loader->setParameters(params);
|
||||
connect(loader, &ItemUrlLoader::ready, [this, loader, item] {
|
||||
|
|
|
@ -19,13 +19,18 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
import QtQuick 2.6
|
||||
import Sailfish.Silica 1.0
|
||||
|
||||
import nl.netsoj.chris.Jellyfin 1.0
|
||||
import nl.netsoj.chris.Jellyfin 1.0 as J
|
||||
|
||||
Column {
|
||||
property var tracks
|
||||
property var audioTracks
|
||||
property var videoTracks
|
||||
property var subtitleTracks
|
||||
|
||||
readonly property int videoTrack: videoSelector.currentItem ? videoSelector.currentItem._index : 0
|
||||
readonly property int audioTrack: audioSelector.currentItem ? audioSelector.currentItem._index : 0
|
||||
readonly property int subtitleTrack: subitleSelector.currentItem._index
|
||||
|
||||
|
||||
ListModel {
|
||||
id: videoModel
|
||||
}
|
||||
|
@ -40,13 +45,13 @@ Column {
|
|||
ComboBox {
|
||||
id: videoSelector
|
||||
label: qsTr("Video track")
|
||||
enabled: videoModel.count > 1
|
||||
enabled: videoTracks.length > 1
|
||||
menu: ContextMenu {
|
||||
Repeater {
|
||||
model: videoModel
|
||||
model: videoTracks
|
||||
MenuItem {
|
||||
readonly property int _index: model.index
|
||||
text: model.displayTitle
|
||||
readonly property int _index: modelData.index
|
||||
text: modelData.displayTitle
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -55,13 +60,13 @@ Column {
|
|||
ComboBox {
|
||||
id: audioSelector
|
||||
label: qsTr("Audio track")
|
||||
enabled: audioModel.count > 1
|
||||
enabled: audioTracks.length > 1
|
||||
menu: ContextMenu {
|
||||
Repeater {
|
||||
model: audioModel
|
||||
model: audioTracks
|
||||
MenuItem {
|
||||
readonly property int _index: model.index
|
||||
text: model.displayTitle
|
||||
readonly property int _index: modelData.index
|
||||
text: modelData.displayTitle
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -70,7 +75,7 @@ Column {
|
|||
ComboBox {
|
||||
id: subitleSelector
|
||||
label: qsTr("Subtitle track")
|
||||
enabled: subtitleModel.count > 0
|
||||
enabled: subtitleTracks.length> 0
|
||||
menu: ContextMenu {
|
||||
MenuItem {
|
||||
readonly property int _index: -1
|
||||
|
@ -78,39 +83,12 @@ Column {
|
|||
text: qsTr("Off")
|
||||
}
|
||||
Repeater {
|
||||
model: subtitleModel
|
||||
model: subtitleTracks
|
||||
MenuItem {
|
||||
readonly property int _index: model.index
|
||||
text: model.displayTitle
|
||||
readonly property int _index: modelData.index
|
||||
text: modelData.displayTitle
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onTracksChanged: {
|
||||
audioModel.clear()
|
||||
subtitleModel.clear()
|
||||
if (typeof tracks === "undefined") {
|
||||
console.log("tracks undefined")
|
||||
return
|
||||
}
|
||||
console.log(tracks)
|
||||
for(var i = 0; i < tracks.length; i++) {
|
||||
var track = tracks[i];
|
||||
switch(track.type) {
|
||||
case MediaStream.Video:
|
||||
videoModel.append(track)
|
||||
break;
|
||||
case MediaStream.Audio:
|
||||
audioModel.append(track)
|
||||
break;
|
||||
case MediaStream.Subtitle:
|
||||
subtitleModel.append(track)
|
||||
break;
|
||||
default:
|
||||
console.log("Ignored " + track.displayTitle + "(" + track.type + ")")
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,8 +26,9 @@ Rectangle {
|
|||
id: videoError
|
||||
//FIXME: Once QTBUG-10822 is resolved, change to J.PlaybackManager
|
||||
property var player
|
||||
property bool showError: false
|
||||
color: pal.palette.overlayBackgroundColor
|
||||
opacity: player.error === MediaPlayer.NoError ? 0.0 : 1.0
|
||||
opacity: showError ? 1.0 : 0.0
|
||||
Behavior on opacity { FadeAnimator {} }
|
||||
|
||||
SilicaItem {
|
||||
|
@ -88,6 +89,20 @@ Rectangle {
|
|||
text: qsTr("Retry")
|
||||
onClicked: player.play()
|
||||
}
|
||||
|
||||
Button {
|
||||
text: qsTr("Hide")
|
||||
onClicked: showError = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: player
|
||||
onErrorChanged: {
|
||||
if (player.error !== MediaPlayer.NoError) {
|
||||
showError = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -76,7 +76,13 @@ BaseDetailPage {
|
|||
VideoTrackSelector {
|
||||
id: trackSelector
|
||||
width: parent.width
|
||||
tracks: itemData.mediaStreams
|
||||
audioTracks: itemData.audioStreams
|
||||
videoTracks: itemData.videoStreams
|
||||
subtitleTracks: itemData.subtitleStreams
|
||||
}
|
||||
|
||||
Label {
|
||||
text: "Video %1, audio %2, subtitle %3".arg(trackSelector.videoTrack).arg(trackSelector.audioTrack).arg(trackSelector.subtitleTrack)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue