diff --git a/QtScrcpy/dialog.cpp b/QtScrcpy/dialog.cpp
index db67f0a..c4a21a6 100644
--- a/QtScrcpy/dialog.cpp
+++ b/QtScrcpy/dialog.cpp
@@ -74,6 +74,10 @@ void Dialog::initUI()
ui->videoSizeBox->addItem("1080");
ui->videoSizeBox->addItem("native");
ui->videoSizeBox->setCurrentIndex(1);
+
+ ui->formatBox->addItem("mp4");
+ ui->formatBox->addItem("mkv");
+ ui->videoSizeBox->setCurrentIndex(0);
}
void Dialog::on_updateDevice_clicked()
@@ -92,8 +96,9 @@ void Dialog::on_startServerBtn_clicked()
QString fileDir(ui->recordPathEdt->text().trimmed());
if (!fileDir.isEmpty()) {
QDateTime dateTime = QDateTime::currentDateTime();
- QString fileName = dateTime.toString("_yyyyMMdd_hhmmss.zzz");
- fileName = windowTitle() + fileName + ".mp4";
+ QString fileName = dateTime.toString("_yyyyMMdd_hhmmss_zzz");
+ QString ext = ui->formatBox->currentText().trimmed();
+ fileName = windowTitle() + fileName + "." + ext;
QDir dir(fileDir);
absFilePath = dir.absoluteFilePath(fileName);
}
diff --git a/QtScrcpy/dialog.ui b/QtScrcpy/dialog.ui
index a2b8cea..55bddf0 100644
--- a/QtScrcpy/dialog.ui
+++ b/QtScrcpy/dialog.ui
@@ -6,19 +6,19 @@
0
0
- 502
+ 639
600
- 502
+ 520
0
- 502
+ 639
16777215
@@ -158,6 +158,20 @@
Config
+ -
+
+
+ record save path:
+
+
+
+ -
+
+
+ format:
+
+
+
-
@@ -165,6 +179,13 @@
+ -
+
+
+ bit rate:
+
+
+
-
@@ -182,28 +203,17 @@
- -
-
-
- bit rate:
-
-
+
-
+
- -
-
-
- record save path:
-
-
-
- -
+
-
true
- -
+
-
select path
diff --git a/QtScrcpy/recorder/recorder.cpp b/QtScrcpy/recorder/recorder.cpp
index e9807fc..ae19bda 100644
--- a/QtScrcpy/recorder/recorder.cpp
+++ b/QtScrcpy/recorder/recorder.cpp
@@ -1,4 +1,5 @@
#include
+#include
#include "recorder.h"
@@ -16,6 +17,7 @@ static const AVRational SCRCPY_TIME_BASE = {1, 1000000}; // timestamps in us
Recorder::Recorder(const QString& fileName)
: m_fileName(fileName)
+ , m_format(guessRecordFormat(fileName))
{
}
@@ -30,11 +32,18 @@ void Recorder::setFrameSize(const QSize &declaredFrameSize)
m_declaredFrameSize = declaredFrameSize;
}
+void Recorder::setFormat(Recorder::RecorderFormat format)
+{
+ m_format = format;
+}
+
bool Recorder::open(AVCodec *inputCodec)
{
- const AVOutputFormat* mp4 = findMp4Muxer();
- if (!mp4) {
- qCritical("Could not find mp4 muxer");
+ QString formatName = recorderGetFormatName(m_format);
+ Q_ASSERT(!formatName.isEmpty());
+ const AVOutputFormat* format = findMuxer(formatName.toUtf8());
+ if (!format) {
+ qCritical("Could not find muxer");
return false;
}
@@ -49,7 +58,7 @@ bool Recorder::open(AVCodec *inputCodec)
// still expects a pointer-to-non-const (it has not be updated accordingly)
//
- m_formatCtx->oformat = (AVOutputFormat*)mp4;
+ m_formatCtx->oformat = (AVOutputFormat*)format;
AVStream* outStream = avformat_new_stream(m_formatCtx, inputCodec);
if (!outStream) {
@@ -115,7 +124,7 @@ bool Recorder::write(AVPacket *packet)
return av_write_frame(m_formatCtx, packet) >= 0;
}
-const AVOutputFormat *Recorder::findMp4Muxer()
+const AVOutputFormat *Recorder::findMuxer(const char* name)
{
#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(58, 9, 100)
void* opaque = Q_NULLPTR;
@@ -127,8 +136,8 @@ const AVOutputFormat *Recorder::findMp4Muxer()
#else
outFormat = av_oformat_next(outFormat);
#endif
- // until null or with name "mp4"
- } while (outFormat && strcmp(outFormat->name, "mp4"));
+ // until null or with name "name"
+ } while (outFormat && strcmp(outFormat->name, name));
return outFormat;
}
@@ -167,3 +176,29 @@ void Recorder::recorderRescalePacket(AVPacket *packet)
AVStream *ostream = m_formatCtx->streams[0];
av_packet_rescale_ts(packet, SCRCPY_TIME_BASE, ostream->time_base);
}
+
+QString Recorder::recorderGetFormatName(Recorder::RecorderFormat format)
+{
+ switch (format) {
+ case RECORDER_FORMAT_MP4: return "mp4";
+ case RECORDER_FORMAT_MKV: return "matroska";
+ default: return "";
+ }
+}
+
+Recorder::RecorderFormat Recorder::guessRecordFormat(const QString &fileName)
+{
+ if (4 > fileName.length()) {
+ return Recorder::RECORDER_FORMAT_NULL;
+ }
+ QFileInfo fileInfo = QFileInfo(fileName);
+ QString ext = fileInfo.suffix();
+ if (0 == ext.compare("mp4")) {
+ return Recorder::RECORDER_FORMAT_MP4;
+ }
+ if (0 == ext.compare("mkv")) {
+ return Recorder::RECORDER_FORMAT_MKV;
+ }
+
+ return Recorder::RECORDER_FORMAT_NULL;
+}
diff --git a/QtScrcpy/recorder/recorder.h b/QtScrcpy/recorder/recorder.h
index 8183db6..31dfc63 100644
--- a/QtScrcpy/recorder/recorder.h
+++ b/QtScrcpy/recorder/recorder.h
@@ -11,24 +11,34 @@ extern "C"
class Recorder
{
public:
+ enum RecorderFormat {
+ RECORDER_FORMAT_NULL = 0,
+ RECORDER_FORMAT_MP4,
+ RECORDER_FORMAT_MKV,
+ };
+
Recorder(const QString& fileName);
virtual ~Recorder();
void setFrameSize(const QSize& declaredFrameSize);
+ void setFormat(Recorder::RecorderFormat format);
bool open(AVCodec* inputCodec);
void close();
bool write(AVPacket* packet);
private:
- const AVOutputFormat* findMp4Muxer();
+ const AVOutputFormat* findMuxer(const char* name);
bool recorderWriteHeader(AVPacket* packet);
void recorderRescalePacket(AVPacket *packet);
+ QString recorderGetFormatName(Recorder::RecorderFormat format);
+ RecorderFormat guessRecordFormat(const QString& fileName);
private:
QString m_fileName = "";
AVFormatContext* m_formatCtx = Q_NULLPTR;
QSize m_declaredFrameSize;
bool m_headerWritten = false;
+ RecorderFormat m_format = RECORDER_FORMAT_NULL;
};
#endif // RECORDER_H
diff --git a/QtScrcpy/videoform.cpp b/QtScrcpy/videoform.cpp
index 14416e1..63cf458 100644
--- a/QtScrcpy/videoform.cpp
+++ b/QtScrcpy/videoform.cpp
@@ -13,11 +13,11 @@
#include
#include "videoform.h"
+#include "recorder.h"
#include "ui_videoform.h"
#include "iconhelper.h"
#include "toolform.h"
#include "controlevent.h"
-#include "recorder.h"
#include "mousetap/mousetap.h"
VideoForm::VideoForm(const QString& serial, quint16 maxSize, quint32 bitRate, const QString& fileName, QWidget *parent) :
diff --git a/QtScrcpy/videoform.h b/QtScrcpy/videoform.h
index 3cd7994..fe048c9 100644
--- a/QtScrcpy/videoform.h
+++ b/QtScrcpy/videoform.h
@@ -44,7 +44,7 @@ private:
void initUI();
void initSignals();
void showToolFrom(bool show = true);
- void postKeyCodeClick(AndroidKeycode keycode);
+ void postKeyCodeClick(AndroidKeycode keycode);
protected:
void mousePressEvent(QMouseEvent *event);