linphone-desktop/linphone-app/ui/modules/Linphone/Chat/ChatAudioPreview.qml

173 lines
No EOL
5.2 KiB
QML

import QtQuick 2.7
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
import Common 1.0
import Linphone 1.0
import Linphone.Styles 1.0
import Utils 1.0
import UtilsCpp 1.0
import LinphoneEnums 1.0
import Units 1.0
import 'Chat.js' as Logic
// =============================================================================
Rectangle{
id: audioPreviewBlock
property bool haveRecorder: RecorderManager.haveVocalRecorder
property RecorderModel vocalRecorder : (haveRecorder ? RecorderManager.getVocalRecorder() : null)
property bool isRecording : (vocalRecorder ? vocalRecorder.state != LinphoneEnums.RecorderStateClosed : false)
property bool isPlaying : vocalPlayer.item && vocalPlayer.item.playbackState === SoundPlayer.PlayingState
onIsRecordingChanged: if(isRecording) {
mediaProgressBar.resume()
}else
mediaProgressBar.stop()
onIsPlayingChanged: isPlaying ? mediaProgressBar.resume() : mediaProgressBar.stop()
Layout.preferredHeight: visible ? ChatAudioPreviewStyle.height : 0
color: ChatAudioPreviewStyle.backgroundColor.color
radius: 0
state: haveRecorder ? 'showed' : 'hidden'
clip: false
Loader {
id: vocalPlayer
active: haveRecorder && vocalRecorder && !isRecording
sourceComponent: SoundPlayer {
source: (haveRecorder && vocalRecorder? vocalRecorder.file : '')
onStopped:{
mediaProgressBar.value = 101
}
Component.onCompleted: {
play()// This will open the file and allow seeking
pause()
mediaProgressBar.value = 101
mediaProgressBar.refresh()
}
}
}
RowLayout{
id: lineLayout
anchors.fill: parent
spacing: 0
ActionButton{
Layout.preferredHeight: iconSize
Layout.preferredWidth: iconSize
Layout.leftMargin: 6
Layout.alignment: Qt.AlignVCenter
isCustom: true
colorSet: ChatAudioPreviewStyle.deleteAction
onClicked: RecorderManager.clearVocalRecorder()
}
VuMeter {
Layout.leftMargin: 6
Layout.rightMargin: 6
Timer {
interval: 50
repeat: true
running: audioPreviewBlock.isRecording
onTriggered: parent.value = audioPreviewBlock.vocalRecorder.getCaptureVolume()
}
visible: audioPreviewBlock.isRecording
}
Item{
Layout.fillHeight: true
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
Layout.topMargin: 10
Layout.bottomMargin: 10
Layout.leftMargin: 6
MediaProgressBar{
id: mediaProgressBar
anchors.fill: parent
waveLeftMargin: !vocalPlayer.item && vocalRecorder ? 10 : 0
progressDuration: !vocalPlayer.item && vocalRecorder? vocalRecorder.getDuration() : 0
progressPosition: !vocalPlayer.item ? progressDuration : 0
value: !vocalPlayer.item ? 0.01 * progressDuration / 5 : 100
stopAtEnd: !audioPreviewBlock.isRecording
resetAtEnd: false
colorSet: isRecording ? ChatAudioPreviewStyle.recordingProgressionWave : ChatAudioPreviewStyle.progressionWave
function progressComputation(t) {
return 1 * Math.sqrt(1 - (t=t/1-1)*t);
}
function refresh(){
if( vocalPlayer.item){
progressPosition = vocalPlayer.item.getPosition()
value = 100 * ( progressPosition / vocalPlayer.item.duration)
}else{// Recording
progressDuration = vocalRecorder.getDuration()
progressPosition = progressDuration
if( value == 0)
value = 1
else
value = value + Math.pow(value,-0.7)
}
}
onEndReached:{
if(vocalPlayer.item)
vocalPlayer.item.stop()
}
onRefreshPositionRequested: refresh()
onSeekRequested: if( vocalPlayer.item){
vocalPlayer.item.seek(ms)
progressPosition = vocalPlayer.item.getPosition()
value = 100 * (progressPosition / vocalPlayer.item.duration)
}
}
}
ActionButton{
Layout.preferredHeight: iconSize
Layout.preferredWidth: iconSize
Layout.rightMargin: ChatStyle.rightButtonMargin
Layout.leftMargin: ChatStyle.rightButtonLMargin
Layout.alignment: Qt.AlignVCenter
isCustom: true
colorSet: audioPreviewBlock.isRecording ? ChatAudioPreviewStyle.stopAction
: (audioPreviewBlock.isPlaying ? ChatAudioPreviewStyle.pauseAction
: ChatAudioPreviewStyle.playAction)
onClicked:{
if(audioPreviewBlock.isRecording){// Stop the record and save the file
audioPreviewBlock.vocalRecorder.stop()
mediaProgressBar.value = 0
}else if(audioPreviewBlock.isPlaying){// Pause the play
vocalPlayer.item.pause()
}else{// Play the audio
vocalPlayer.item.play()
}
}
}
}
states: [
State {
name: "hidden"
PropertyChanges { target: audioPreviewBlock; opacity: 0 ; visible: false }
},
State {
name: "showed"
PropertyChanges { target: audioPreviewBlock; opacity: 1 ; visible: true }
}
]
transitions: [
Transition {
from: "*"; to: "showed"
SequentialAnimation{
ScriptAction{ script: audioPreviewBlock.visible = true }
ScriptAction{ script: audioPreviewBlock.vocalRecorder.start() }
NumberAnimation{ properties: "opacity"; easing.type: Easing.OutBounce; duration: 250 }
}
},
Transition {
from: "*"; to: "hidden"
SequentialAnimation{
NumberAnimation{ properties: "opacity"; duration: 250 }
ScriptAction{ script: audioPreviewBlock.visible = false }
}
}
]
}