前沿
之前开发了一个云真机软件,参考的是QtScrcpy这个工程来开发。
开发的时间比较旧了,当时参考的这个工程还是一年多前了,现在回头再看看,源码解析一下这个工程,顺便也重新学习一下。
QtScrcpy地址
解析的版本是v2.1.2
音频处理
使用了sndcpy库,同样也是通过socket连接手机服务实现
sndcpy地址
主要实现的类在audiooutput.cpp中
void AudioOutput::startAudioOutput()
{
if (m_audioOutput) {
return;
}
// 使用QAudioOutput来播放音频
QAudioFormat format;
format.setSampleRate(48000);
format.setChannelCount(2);
format.setSampleSize(16);
format.setCodec("audio/pcm");
format.setByteOrder(QAudioFormat::LittleEndian);
format.setSampleType(QAudioFormat::SignedInt);
QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice());
if (!info.isFormatSupported(format)) {
qWarning() << "AudioOutput::audio format not supported, cannot play audio.";
return;
}
m_audioOutput = new QAudioOutput(format, this);
connect(m_audioOutput, &QAudioOutput::stateChanged, this, [](QAudio::State state) {
qInfo() << "AudioOutput::audio state changed:" << state;
});
m_audioOutput->setBufferSize(48000*2*15/1000 * 20);
m_outputDevice = m_audioOutput->start();
}
void AudioOutput::startRecvData(int port)
{
// 省略
// 实时读取音频数据,将音频数据输入到QAudioOutput中进行播放
connect(audioSocket, &QIODevice::readyRead, audioSocket, [this, audioSocket]() {
qint64 recv = audioSocket->bytesAvailable();
//qDebug() << "AudioOutput::recv data:" << recv;
if (!m_outputDevice) {
return;
}
if (m_buffer.capacity() < recv) {
m_buffer.reserve(recv);
}
qint64 count = audioSocket->read(m_buffer.data(), audioSocket->bytesAvailable());
m_outputDevice->write(m_buffer.data(), count);
});
// 省略
}