#include "widget.h"
#include "ui_widget.h"
#include "capturerecorder.h"
#include <vector>
#include <QDebug>
#include <QMediaFormat>
#include <QMediaRecorder>
#include <QMediaDevices>
#include <QAudioDevice>
#include <QTime>
#include <QDesktopServices>
#include <QDir>
#include <QStandardPaths>
#include <QFileDialog>
#include <QDateTime>
#include <QMessageBox>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
setWindowFlags(windowFlags() & ~Qt::WindowMaximizeButtonHint);
this->setFixedWidth(400);
this->setFixedHeight(400);
ui->cmbOutputFormat->addItem("WMV", QMediaFormat::WMV);
ui->cmbOutputFormat->addItem("AVI", QMediaFormat::AVI);
ui->cmbOutputFormat->addItem("MP4", QMediaFormat::MPEG4);
ui->cmbOutputFormat->addItem("WebM", QMediaFormat::WebM);
ui->cmbOutputFormat->addItem("MP3", QMediaFormat::MP3);
ui->cmbOutputFormat->setCurrentIndex(2);
std::vector<int> frameRate = {0, 1, 5, 10, 24, 25, 30, 50, 60};
for (auto i : frameRate) {
if (i == 0) ui->cmbVideoFrameRate->addItem("自适应", i);
else ui->cmbVideoFrameRate->addItem(QString::number(i), i);
}
ui->cmbVideoCodec->addItem("MPEG4", (int)QMediaFormat::VideoCodec::MPEG4);
ui->cmbVideoCodec->addItem("H264", (int)QMediaFormat::VideoCodec::H264);
ui->cmbVideoCodec->addItem("H265", (int)QMediaFormat::VideoCodec::H265);
ui->cmbVideoCodec->addItem("VP8", (int)QMediaFormat::VideoCodec::VP8);
ui->cmbVideoCodec->addItem("VP9", (int)QMediaFormat::VideoCodec::VP9);
ui->cmbVideoCodec->setCurrentIndex(1);
ui->cmbVideoQuality->addItem("非常低", QMediaRecorder::VeryLowQuality);
ui->cmbVideoQuality->addItem("低", QMediaRecorder::LowQuality);
ui->cmbVideoQuality->addItem("默认", QMediaRecorder::NormalQuality);
ui->cmbVideoQuality->addItem("高", QMediaRecorder::HighQuality);
ui->cmbVideoQuality->addItem("非常高", QMediaRecorder::VeryHighQuality);
ui->cmbVideoQuality->setCurrentIndex(2);
connect(ui->btnRefresh, SIGNAL(clicked()), SLOT(slotRefreshAudioInput()));
connect(ui->btnSelectDir, SIGNAL(clicked()), SLOT(slotSelectDirClicked()));
connect(ui->btnOpenDir, SIGNAL(clicked()), SLOT(slotOpenDirClicked()));
connect(ui->btnRestore, SIGNAL(clicked()), SLOT(slotRestoreClicked()));
connect(ui->btnStart, SIGNAL(clicked()), SLOT(slotStart()));
connect(ui->btnStop, SIGNAL(clicked()), SLOT(slotStop()));
slotRefreshAudioInput();
ui->edtOutput->setText(QDir::homePath());
ui->edtOutput->setText(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation));
ui->chkScreen->setChecked(true);
ui->chkAudio->setChecked(true);
ui->lblStatus->setText("就绪");
ui->btnStart->setText("开始");
ui->btnStop->setEnabled(false);
}
Widget::~Widget()
{
delete ui;
}
void Widget::slotRefreshAudioInput()
{
const auto &devices = QMediaDevices::audioInputs();
ui->cmbAudioInput->clear();
for (const QAudioDevice &device : devices) {
ui->cmbAudioInput->addItem(device.description());
}
ui->cmbAudioInput->setCurrentIndex(0);
}
void Widget::slotOpenDirClicked()
{
QString path = ui->edtOutput->text();
if (path.isEmpty() || !QDir(path).exists()) {
return ;
}
QUrl url("file:" + path, QUrl::TolerantMode);
if (!QDesktopServices::openUrl(url)){
qDebug() << url << "打开失败";
}
}
void Widget::slotSelectDirClicked()
{
QString dir = QFileDialog::getExistingDirectory(this,
"请选择输出目录",
"/",
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
if (!dir.isEmpty()) {
ui->edtOutput->setText(dir);
}
}
void Widget::slotRestoreClicked()
{
ui->cmbOutputFormat->setCurrentIndex(2);
ui->cmbVideoFrameRate->setCurrentIndex(0);
ui->cmbVideoCodec->setCurrentIndex(1);
ui->cmbVideoQuality->setCurrentIndex(2);
}
void Widget::slotStart()
{
if (m_running) {
if (m_paused) {
m_paused = false;
ui->btnStart->setText("暂停");
ui->btnStart->setIcon(QIcon(":/images/pause.png"));
m_pCapture->resume();
} else {
m_paused = true;
ui->btnStart->setText("继续");
ui->btnStart->setIcon(QIcon(":/images/start.png"));
m_pCapture->pause();
}
} else {
QString outputPath = ui->edtOutput->text();
QDir output(outputPath);
if (outputPath.isEmpty() || !output.exists()) {
QMessageBox::critical(this, "错误", "请选择输出目录");
return ;
}
if (!ui->chkAudio->isChecked() && !ui->chkScreen->isChecked()) {
QMessageBox::critical(this, "错误", "没有要录制的内容");
return ;
}
QString fileName = QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss");
if (!m_pCapture) {
m_pCapture = new CaptureRecorder(this);
connect(m_pCapture, &CaptureRecorder::durationChanged, this, &Widget::slotDurationChanged);
connect(m_pCapture, &CaptureRecorder::recorderStateChanged, this, &Widget::slotRecorderStateChanged);
}
m_pCapture->enableScreenCapture(ui->chkScreen->isChecked());
if (ui->chkAudio->isChecked()) {
//设置声音输入设备
}
ui->btnStart->setText("暂停");
ui->btnStart->setIcon(QIcon(":/images/pause.png"));
ui->btnStop->setEnabled(true);
m_paused = false;
m_running = true;
m_pCapture->setVideoFrameRate(ui->cmbVideoFrameRate->currentData().toInt());
m_pCapture->setVideoCodec(ui->cmbVideoCodec->currentData().toInt());
m_pCapture->setQuality(ui->cmbVideoCodec->currentData().toInt());
m_pCapture->setFileFormat(ui->cmbOutputFormat->currentData().toInt());
m_pCapture->setOutputLocation(output.filePath(fileName));
m_pCapture->record();
}
}
void Widget::slotStop()
{
if (m_running) {
m_running = false;
m_paused = false;
ui->btnStart->setText("开始");
ui->btnStart->setIcon(QIcon(":/images/start.png"));
ui->btnStop->setEnabled(false);
m_pCapture->stop();
}
}
void Widget::slotDurationChanged(qint64 duration)
{
m_duration = QDateTime::fromMSecsSinceEpoch(duration, QTimeZone(QTimeZone::UTC));
ui->lblStatus->setText(QString("录制中: %1").arg(m_duration.toString("hh:mm:ss")));
}
void Widget::slotRecorderStateChanged(QMediaRecorder::RecorderState state)
{
if (state == QMediaRecorder::RecorderState::StoppedState) {
ui->lblStatus->setText(QString("已停止: %1").arg(m_duration.toString("hh:mm:ss")));
} else if (state == QMediaRecorder::RecorderState::RecordingState) {
ui->lblStatus->setText(QString("录制中: %1").arg(m_duration.toString("hh:mm:ss")));
} else if (state == QMediaRecorder::RecorderState::PausedState) {
ui->lblStatus->setText(QString("暂停中: %1").arg(m_duration.toString("hh:mm:ss")));
}
}