File indexing completed on 2024-11-10 05:11:08

0001 /*
0002  * Copyright 2023 by Aditya Mehra <aix.m@outlook.com>
0003  *
0004  * Licensed under the Apache License, Version 2.0 (the "License");
0005  * you may not use this file except in compliance with the License.
0006  * You may obtain a copy of the License at
0007  *
0008  *    http://www.apache.org/licenses/LICENSE-2.0
0009  *
0010  * Unless required by applicable law or agreed to in writing, software
0011  * distributed under the License is distributed on an "AS IS" BASIS,
0012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013  * See the License for the specific language governing permissions and
0014  * limitations under the License.
0015  *
0016  */
0017 
0018 #include "audioproviderservice.h"
0019 
0020 AudioProviderService::AudioProviderService(QObject *parent)
0021     : QObject(parent)
0022 {
0023     QAudioDevice info(QMediaDevices::defaultAudioOutput());
0024     m_format = info.preferredFormat();
0025     m_currentMediaState = AudioProviderService::NoMedia;
0026     m_currentPlaybackState = AudioProviderService::StoppedState;
0027 }
0028 
0029 AudioProviderService::~AudioProviderService()
0030 {
0031     m_audioSink->deleteLater();
0032     m_audioStreamDevice->deleteLater();
0033     emit destroyedService();
0034 }
0035 
0036 void AudioProviderService::syncStates()
0037 {
0038     switch (m_audioSink->state()) {
0039     case QAudio::ActiveState:
0040         m_currentPlaybackState = AudioProviderService::PlayingState;
0041         break;
0042     case QAudio::SuspendedState:
0043         m_currentPlaybackState = AudioProviderService::PausedState;
0044         break;
0045     case QAudio::StoppedState:
0046         m_currentPlaybackState = AudioProviderService::StoppedState;
0047         break;
0048     default:
0049         break;
0050     }
0051     emit playBackStateChanged(m_currentPlaybackState);
0052     emit mediaStateChanged(m_currentMediaState);
0053 }
0054 
0055 void AudioProviderService::mediaPlay(const QUrl &url)
0056 {
0057     m_audioStreamDevice = new AudioStreamDevice(this);
0058     emit mediaStateChanged(m_currentMediaState);
0059     emit playBackStateChanged(m_currentPlaybackState);
0060     m_currentMediaState = AudioProviderService::LoadingMedia;
0061     emit mediaStateChanged(m_currentMediaState);
0062     QObject::connect(m_audioStreamDevice, &AudioStreamDevice::bufferingMedia, this, &AudioProviderService::notifyBufferingMedia);
0063     QObject::connect(m_audioStreamDevice, &AudioStreamDevice::bufferedMedia, this, &AudioProviderService::notifyBufferedMedia);
0064     QObject::connect(m_audioStreamDevice, &AudioStreamDevice::stalledMedia, this, &AudioProviderService::notifyStalledMedia);
0065     QObject::connect(m_audioStreamDevice, &AudioStreamDevice::endOfMedia, this, &AudioProviderService::notifyEndOfMedia);
0066     QObject::connect(m_audioStreamDevice, &AudioStreamDevice::invalidMedia, this, &AudioProviderService::notifyInvalidMedia);
0067     QObject::connect(m_audioStreamDevice, &AudioStreamDevice::spectrumChanged, this, &AudioProviderService::spectrumUpdated);
0068     QObject::connect(m_audioStreamDevice, &AudioStreamDevice::positionChanged, this, &AudioProviderService::positionUpdated);
0069     QObject::connect(m_audioStreamDevice, &AudioStreamDevice::durationChanged, this, &AudioProviderService::durationUpdated);
0070 
0071     if (!m_audioStreamDevice->init(m_format)) {
0072         qWarning() << "AudioStreamDevice Could Not Be Initialized";
0073     }
0074     m_audioSink = new QAudioSink(QMediaDevices::defaultAudioOutput(), m_format, this);
0075     m_currentMediaUrl = url;
0076     m_audioSink->start(m_audioStreamDevice);
0077     m_audioStreamDevice->play(url);
0078     if (m_audioSink->state() == QAudio::ActiveState) {
0079         m_currentPlaybackState = AudioProviderService::PlayingState;
0080         emit playBackStateChanged(m_currentPlaybackState);
0081         m_currentMediaState = AudioProviderService::LoadedMedia;
0082         emit mediaStateChanged(m_currentMediaState);
0083     }
0084 }
0085 
0086 void AudioProviderService::mediaStop()
0087 {
0088     m_audioStreamDevice->stop();
0089     m_audioSink->stop();
0090     m_audioSink->deleteLater();
0091     m_audioStreamDevice->deleteLater();
0092     m_currentPlaybackState = AudioProviderService::StoppedState;
0093     emit playBackStateChanged(m_currentPlaybackState);
0094     m_currentMediaState = AudioProviderService::NoMedia;
0095     emit mediaStateChanged(m_currentMediaState);
0096 }
0097 
0098 void AudioProviderService::mediaPause()
0099 {
0100     m_audioSink->suspend();
0101     m_currentPlaybackState = AudioProviderService::PausedState;
0102     emit playBackStateChanged(m_currentPlaybackState);
0103 }
0104 
0105 void AudioProviderService::mediaContinue()
0106 {
0107     m_audioSink->resume();
0108     m_currentPlaybackState = AudioProviderService::PlayingState;
0109     emit playBackStateChanged(m_currentPlaybackState);
0110 }
0111 
0112 void AudioProviderService::mediaRestart()
0113 {
0114     mediaPlay(m_currentMediaUrl);
0115 }
0116 
0117 void AudioProviderService::mediaSeek(qint64 seekValue)
0118 {
0119     seekValue = seekValue - (seekValue % 1000);
0120     m_audioSink->suspend();
0121     m_audioStreamDevice->seek(seekValue);
0122     m_audioStreamDevice->seekFrom(seekValue);
0123     m_audioSink->resume();
0124 }
0125 
0126 void AudioProviderService::notifyBufferingMedia()
0127 {
0128     m_currentMediaState = AudioProviderService::BufferingMedia;
0129     emit mediaStateChanged(m_currentMediaState);
0130 }
0131 
0132 void AudioProviderService::notifyBufferedMedia()
0133 {
0134     if(m_currentMediaState != AudioProviderService::NoMedia){
0135         m_currentMediaState = AudioProviderService::BufferedMedia;
0136         emit mediaStateChanged(m_currentMediaState);
0137     }
0138 }
0139 
0140 void AudioProviderService::notifyStalledMedia()
0141 {
0142     m_currentMediaState = AudioProviderService::StalledMedia;
0143     emit mediaStateChanged(m_currentMediaState);
0144 }
0145 
0146 void AudioProviderService::notifyEndOfMedia()
0147 {
0148     m_currentMediaState = AudioProviderService::EndOfMedia;
0149     emit mediaStateChanged(m_currentMediaState);
0150 }
0151 
0152 void AudioProviderService::notifyInvalidMedia()
0153 {
0154     m_audioSink->suspend();
0155     QTimer::singleShot(2000, this, [this](){
0156         m_audioStreamDevice->stop();
0157         m_audioSink->stop();
0158         m_currentPlaybackState = AudioProviderService::StoppedState;
0159         emit playBackStateChanged(m_currentPlaybackState);
0160     });
0161     m_currentMediaState = AudioProviderService::InvalidMedia;
0162     emit mediaStateChanged(m_currentMediaState);
0163 }
0164 
0165 void AudioProviderService::spectrumUpdated(QVector<double> spectrum)
0166 {
0167     emit spectrumChanged(spectrum);
0168 }
0169 
0170 void AudioProviderService::durationUpdated(qint64 duration)
0171 {
0172     emit durationChanged(duration);
0173 }
0174 
0175 void AudioProviderService::positionUpdated(qint64 position)
0176 {
0177     emit positionChanged(position);
0178 }