diff --git a/TODO.md b/TODO.md index ca38ce4c..c8d7f9bb 100644 --- a/TODO.md +++ b/TODO.md @@ -17,6 +17,7 @@ - Video bug: when media is done playing, clicking on progress slider always bring back to the beginning no matter where - Video: missing buttons and small size problems + - Audio: online playback is buggy, must download+play file - Refactor EventContent - No background/padding around medias diff --git a/src/qml/Base/MediaPlayer/AudioPlayer.qml b/src/qml/Base/MediaPlayer/AudioPlayer.qml new file mode 100644 index 00000000..51cd8e22 --- /dev/null +++ b/src/qml/Base/MediaPlayer/AudioPlayer.qml @@ -0,0 +1,23 @@ +import QtQuick 2.12 +import QtAV 1.7 + +OSD { + id: osd + audioOnly: true + media: audioPlayer + + implicitWidth: osd.width + implicitHeight: osd.height + + + property alias source: audioPlayer.source + + + MediaPlayer { + id: audioPlayer + autoLoad: window.settings.media.autoLoad + autoPlay: window.settings.media.autoPlay + volume: window.settings.media.defaultVolume / 100 + muted: window.settings.media.startMuted + } +} diff --git a/src/qml/Base/MediaPlayer/OSD.qml b/src/qml/Base/MediaPlayer/OSD.qml index 4a7d59f0..995ad79e 100644 --- a/src/qml/Base/MediaPlayer/OSD.qml +++ b/src/qml/Base/MediaPlayer/OSD.qml @@ -10,7 +10,8 @@ HColumnLayout { transform: Scale { id: osdScaleTransform - yScale: osdHover.hovered || + yScale: audioOnly || + osdHover.hovered || media.playbackState !== MediaPlayer.PlayingState || osd.showup ? 1 : 0 @@ -20,19 +21,23 @@ HColumnLayout { } - property Item media: parent // QtAV.Video or QtAV.Audio + property QtObject media: parent // QtAV.Video or QtAV.MediaPlayer + property bool audioOnly: false property bool showup: false - property bool enableFullScreen: false property bool fullScreen: false + property real savedAspectRatio: 16 / 9 property int savedDuration: 0 + readonly property real aspectRatio: media.sourceAspectRatio || 0 readonly property int duration: media.duration readonly property int boundPosition: - Math.min(media.position, savedDuration) + savedDuration ? + Math.min(media.position, savedDuration) : media.position onShowupChanged: if (showup) osdHideTimer.restart() onDurationChanged: if (duration) savedDuration = duration + onAspectRatioChanged: if (aspectRatio) savedAspectRatio = aspectRatio function togglePlay() { @@ -42,7 +47,7 @@ HColumnLayout { function seekToPosition(pos) { // pos: 0.0 to 1.0 if (media.playbackState === MediaPlayer.StoppedState) media.play() - if (media.seekable) media.seek(pos * savedDuration) + if (media.seekable) media.seek(pos * (savedDuration || boundPosition)) } @@ -72,7 +77,9 @@ HColumnLayout { HToolTip { id: previewToolTip x: timeSlider.mouseArea.mouseX - width / 2 - visible: preview.implicitWidth >= + visible: ! audioOnly && + + preview.implicitWidth >= previewLabel.implicitWidth + previewLabel.padding && preview.implicitHeight >= @@ -101,7 +108,7 @@ HColumnLayout { media.height - osd.height - theme.spacing ) implicitWidth: Math.min( - implicitHeight * media.savedAspectRatio, + implicitHeight * savedAspectRatio, media.width - theme.spacing, ) file: media.source @@ -217,16 +224,16 @@ HColumnLayout { } OSDLabel { - text: boundPosition && savedDuration ? + text: boundPosition && savedDuration ? - qsTr("%1 / %2") - .arg(Utils.formatDuration(boundPosition)) - .arg(Utils.formatDuration(savedDuration)) : + qsTr("%1 / %2") + .arg(Utils.formatDuration(boundPosition)) + .arg(Utils.formatDuration(savedDuration)) : - boundPosition || savedDuration ? - Utils.formatDuration(boundPosition || savedDuration) : + boundPosition || savedDuration ? + Utils.formatDuration(boundPosition || savedDuration) : - "" + "" } HSpacer {} @@ -258,6 +265,7 @@ HColumnLayout { OSDButton { id: fullScreenButton + visible: ! audioOnly icon.name: "player-fullscreen" + (fullScreen ? "-exit" : "") toolTip.text: fullScreen ? qsTr("Exit fullscreen") : qsTr("Fullscreen") diff --git a/src/qml/Base/MediaPlayer/VideoPlayer.qml b/src/qml/Base/MediaPlayer/VideoPlayer.qml index ef7d8497..02fc84d0 100644 --- a/src/qml/Base/MediaPlayer/VideoPlayer.qml +++ b/src/qml/Base/MediaPlayer/VideoPlayer.qml @@ -9,7 +9,7 @@ Video { volume: window.settings.media.defaultVolume / 100 muted: window.settings.media.startMuted implicitWidth: fullScreen ? window.width : 640 - implicitHeight: fullScreen ? window.height : (width / savedAspectRatio) + implicitHeight: fullScreen ? window.height : (width / osd.savedAspectRatio) property bool hovered: false @@ -18,11 +18,6 @@ Video { property int oldVisibility: Window.Windowed property QtObject oldParent: video.parent - property real savedAspectRatio: 16 / 9 - - - onSourceAspectRatioChanged: - if (sourceAspectRatio) savedAspectRatio = sourceAspectRatio onFullScreenChanged: { if (fullScreen) { @@ -69,6 +64,5 @@ Video { id: osd width: parent.width anchors.bottom: parent.bottom - enableFullScreen: true } } diff --git a/src/qml/Chat/Timeline/EventAudio.qml b/src/qml/Chat/Timeline/EventAudio.qml new file mode 100644 index 00000000..979f69de --- /dev/null +++ b/src/qml/Chat/Timeline/EventAudio.qml @@ -0,0 +1,20 @@ +import QtQuick 2.12 +import QtQuick.Layouts 1.12 +import QtAV 1.7 +import "../../Base" +import "../../Base/MediaPlayer" +import "../../utils.js" as Utils + +AudioPlayer { + id: audio + width: Math.min( + mainColumn.width - eventContent.spacing * 2, + theme.chat.message.audioWidth, + ) + + HoverHandler { + onHoveredChanged: + eventDelegate.hoveredMediaTypeUrl = + hovered ? [EventDelegate.Media.Audio, audio.source] : [] + } +} diff --git a/src/qml/Chat/Timeline/EventDelegate.qml b/src/qml/Chat/Timeline/EventDelegate.qml index 1d41ed0d..2219fb09 100644 --- a/src/qml/Chat/Timeline/EventDelegate.qml +++ b/src/qml/Chat/Timeline/EventDelegate.qml @@ -130,6 +130,12 @@ Column { contextMenu.media[0] === EventDelegate.Media.Image ? qsTr("Copy image address") : + contextMenu.media[0] === EventDelegate.Media.Video ? + qsTr("Copy video address") : + + contextMenu.media[0] === EventDelegate.Media.Audio ? + qsTr("Copy audio address") : + qsTr("Copy media address") visible: Boolean(text) diff --git a/src/qml/Chat/Timeline/EventMediaLoader.qml b/src/qml/Chat/Timeline/EventMediaLoader.qml index 365ad37d..5850fa2a 100644 --- a/src/qml/Chat/Timeline/EventMediaLoader.qml +++ b/src/qml/Chat/Timeline/EventMediaLoader.qml @@ -69,6 +69,10 @@ HLoader { var file = "EventVideo.qml" var props = { source: mediaUrl } + } else if (type === EventDelegate.Media.Audio) { + var file = "EventAudio.qml" + var props = { source: mediaUrl } + } else { return } loader.setSource(file, props) diff --git a/src/qml/Chat/Timeline/EventVideo.qml b/src/qml/Chat/Timeline/EventVideo.qml index 12af45da..66ee3754 100644 --- a/src/qml/Chat/Timeline/EventVideo.qml +++ b/src/qml/Chat/Timeline/EventVideo.qml @@ -12,8 +12,7 @@ VideoPlayer { theme.chat.message.videoWidth, ) - onHoveredChanged: { + onHoveredChanged: eventDelegate.hoveredMediaTypeUrl = hovered ? [EventDelegate.Media.Video, video.source] : [] - } } diff --git a/src/themes/Default.qpl b/src/themes/Default.qpl index 743ba392..d367bdd1 100644 --- a/src/themes/Default.qpl +++ b/src/themes/Default.qpl @@ -334,6 +334,7 @@ chat: int thumbnailWidth: 256 int videoWidth: 512 + int audioWidth: 512 daybreak: color background: colors.strongBackground