From d7e9b7809f364f30ce33954af0aacdfa4b90eae4 Mon Sep 17 00:00:00 2001 From: rankun Date: Wed, 15 Jan 2020 19:52:31 +0800 Subject: [PATCH] feat: sync scrcpy --- QtScrcpy/QtScrcpy.pro | 2 +- QtScrcpy/device/recorder/recorder.cpp | 80 ++++++++++++++++++++------ QtScrcpy/device/recorder/recorder.h | 5 ++ QtScrcpy/device/server/server.cpp | 9 +-- QtScrcpy/main.cpp | 11 +++- README.md | 4 +- README_zh.md | 4 +- docs/TODO.md | 10 +--- third_party/scrcpy-server | Bin 0 -> 26142 bytes 9 files changed, 86 insertions(+), 39 deletions(-) create mode 100644 third_party/scrcpy-server diff --git a/QtScrcpy/QtScrcpy.pro b/QtScrcpy/QtScrcpy.pro index 41e46bc..8ac2b36 100644 --- a/QtScrcpy/QtScrcpy.pro +++ b/QtScrcpy/QtScrcpy.pro @@ -140,7 +140,7 @@ macos { -L$$PWD/../third_party/ffmpeg/lib -lswscale.5 # mac bundle file - APP_SCRCPY_SERVER.files = $$files($$PWD/../third_party/scrcpy-server.jar) + APP_SCRCPY_SERVER.files = $$files($$PWD/../third_party/scrcpy-server) APP_SCRCPY_SERVER.path = Contents/MacOS QMAKE_BUNDLE_DATA += APP_SCRCPY_SERVER diff --git a/QtScrcpy/device/recorder/recorder.cpp b/QtScrcpy/device/recorder/recorder.cpp index f37d19f..b418810 100644 --- a/QtScrcpy/device/recorder/recorder.cpp +++ b/QtScrcpy/device/recorder/recorder.cpp @@ -1,5 +1,6 @@ #include #include +#include #include "compat.h" #include "recorder.h" @@ -24,6 +25,10 @@ Recorder::RecordPacket* Recorder::packetNew(const AVPacket *packet) { if (!rec) { return Q_NULLPTR; } + + // av_packet_ref() does not initialize all fields in old FFmpeg versions + av_init_packet(&rec->packet); + if (av_packet_ref(&rec->packet, packet)) { delete rec; return Q_NULLPTR; @@ -121,6 +126,10 @@ bool Recorder::open(const AVCodec* inputCodec) m_formatCtx->oformat = (AVOutputFormat*)format; + QString comment = "Recorded by QtScrcpy " + QCoreApplication::applicationVersion(); + av_dict_set(&m_formatCtx->metadata, "comment", + comment.toUtf8(), 0); + AVStream* outStream = avformat_new_stream(m_formatCtx, inputCodec); if (!outStream) { avformat_free_context(m_formatCtx); @@ -152,7 +161,7 @@ bool Recorder::open(const AVCodec* inputCodec) avformat_free_context(m_formatCtx); m_formatCtx = Q_NULLPTR; return false; - } + } return true; } @@ -160,11 +169,17 @@ bool Recorder::open(const AVCodec* inputCodec) void Recorder::close() { if (Q_NULLPTR != m_formatCtx) { - int ret = av_write_trailer(m_formatCtx); - if (ret < 0) { - qCritical(QString("Failed to write trailer to %1").arg(m_fileName).toUtf8().toStdString().c_str()); + if (m_headerWritten) { + int ret = av_write_trailer(m_formatCtx); + if (ret < 0) { + qCritical(QString("Failed to write trailer to %1").arg(m_fileName).toUtf8().toStdString().c_str()); + m_failed = true; + } else { + qInfo(QString("success record %1").arg(m_fileName).toStdString().c_str()); + } } else { - qInfo(QString("success record %1").arg(m_fileName).toStdString().c_str()); + // the recorded file is empty + m_failed = true; } avio_close(m_formatCtx->pb); avformat_free_context(m_formatCtx); @@ -274,23 +289,53 @@ Recorder::RecorderFormat Recorder::guessRecordFormat(const QString &fileName) void Recorder::run() { for (;;) { - QMutexLocker locker(&m_mutex); - while (!m_stopped && queueIsEmpty(&m_queue)) { - m_recvDataCond.wait(&m_mutex); + RecordPacket *rec = Q_NULLPTR; + { + QMutexLocker locker(&m_mutex); + while (!m_stopped && queueIsEmpty(&m_queue)) { + m_recvDataCond.wait(&m_mutex); + } + + // if stopped is set, continue to process the remaining events (to + // finish the recording) before actually stopping + if (m_stopped && queueIsEmpty(&m_queue)) { + RecordPacket* last = m_previous; + if (last) { + // assign an arbitrary duration to the last packet + last->packet.duration = 100000; + bool ok = write(&last->packet); + if (!ok) { + // failing to write the last frame is not very serious, no + // future frame may depend on it, so the resulting file + // will still be valid + qWarning("Could not record last packet"); + } + packetDelete(last); + } + break; + } + + rec = queueTake(&m_queue); } - // if stopped is set, continue to process the remaining events (to - // finish the recording) before actually stopping - if (m_stopped && queueIsEmpty(&m_queue)) { - break; + // recorder->previous is only written from this thread, no need to lock + RecordPacket* previous = m_previous; + m_previous = rec; + + if (!previous) { + // we just received the first packet + continue; } - RecordPacket *rec = queueTake(&m_queue); + // config packets have no PTS, we must ignore them + if (rec->packet.pts != AV_NOPTS_VALUE + && previous->packet.pts != AV_NOPTS_VALUE) { + // we now know the duration of the previous packet + previous->packet.duration = rec->packet.pts - previous->packet.pts; + } - //mutex_unlock(recorder->mutex); - - bool ok = write(&rec->packet); - packetDelete(rec); + bool ok = write(&previous->packet); + packetDelete(previous); if (!ok) { qCritical("Could not record packet"); @@ -300,7 +345,6 @@ void Recorder::run() { queueClear(&m_queue); break; } - } qDebug("Recorder thread ended"); diff --git a/QtScrcpy/device/recorder/recorder.h b/QtScrcpy/device/recorder/recorder.h index 35927cd..da9695c 100644 --- a/QtScrcpy/device/recorder/recorder.h +++ b/QtScrcpy/device/recorder/recorder.h @@ -73,6 +73,11 @@ private: bool m_stopped = false; // set on recorder_stop() by the stream reader bool m_failed = false; // set on packet write failure RecorderQueue m_queue; + // we can write a packet only once we received the next one so that we can + // set its duration (next_pts - current_pts) + // "previous" is only accessed from the recorder thread, so it does not + // need to be protected by the mutex + RecordPacket* m_previous = Q_NULLPTR; }; #endif // RECORDER_H diff --git a/QtScrcpy/device/server/server.cpp b/QtScrcpy/device/server/server.cpp index a4f3d96..f60da81 100644 --- a/QtScrcpy/device/server/server.cpp +++ b/QtScrcpy/device/server/server.cpp @@ -56,7 +56,7 @@ const QString& Server::getServerPath() m_serverPath = QString::fromLocal8Bit(qgetenv("QTSCRCPY_SERVER_PATH")); QFileInfo fileInfo(m_serverPath); if (m_serverPath.isEmpty() || !fileInfo.isFile()) { - m_serverPath = QCoreApplication::applicationDirPath() + "/scrcpy-server.jar"; + m_serverPath = QCoreApplication::applicationDirPath() + "/scrcpy-server"; } } return m_serverPath; @@ -129,10 +129,7 @@ bool Server::execute() args << "app_process"; args << "/"; // unused; args << "com.genymobile.scrcpy.Server"; - // version - QStringList versionList = QCoreApplication::applicationVersion().split("."); - QString version = versionList[0] + "." + versionList[1] + "." + versionList[2]; - args << version; + args << QCoreApplication::applicationVersion(); args << QString::number(m_params.maxSize); args << QString::number(m_params.bitRate); args << QString::number(m_params.maxFps); @@ -145,7 +142,7 @@ bool Server::execute() args << "true"; // always send frame meta (packet boundaries + timestamp) args << (m_params.control ? "true" : "false"); - // adb -s P7C0218510000537 shell CLASSPATH=/data/local/tmp/scrcpy-server.jar app_process / com.genymobile.scrcpy.Server 0 8000000 false + // adb -s P7C0218510000537 shell CLASSPATH=/data/local/tmp/scrcpy-server app_process / com.genymobile.scrcpy.Server 0 8000000 false // mark: crop input format: "width:height:x:y" or - for no crop, for example: "100:200:0:0" // 这条adb命令是阻塞运行的,m_serverProcess进程不会退出了 m_serverProcess.execute(m_params.serial, args); diff --git a/QtScrcpy/main.cpp b/QtScrcpy/main.cpp index d123e4e..e0182a9 100644 --- a/QtScrcpy/main.cpp +++ b/QtScrcpy/main.cpp @@ -30,6 +30,11 @@ int main(int argc, char *argv[]) qDebug() << a.applicationVersion(); qDebug() << a.applicationName(); + //update version + QStringList versionList = QCoreApplication::applicationVersion().split("."); + QString version = versionList[0] + "." + versionList[1] + "." + versionList[2]; + a.setApplicationVersion(version); + installTranslator(); #if defined(Q_OS_WIN32) || defined(Q_OS_OSX) MouseTap::getInstance()->initMouseEventTap(); @@ -37,13 +42,13 @@ int main(int argc, char *argv[]) #ifdef Q_OS_WIN32 qputenv("QTSCRCPY_ADB_PATH", "../../../../third_party/adb/win/adb.exe"); - qputenv("QTSCRCPY_SERVER_PATH", "../../../../third_party/scrcpy-server.jar"); + qputenv("QTSCRCPY_SERVER_PATH", "../../../../third_party/scrcpy-server"); qputenv("QTSCRCPY_KEYMAP_PATH", "../../../../keymap"); #endif #ifdef Q_OS_LINUX qputenv("QTSCRCPY_ADB_PATH", "../../../third_party/adb/linux/adb"); - qputenv("QTSCRCPY_SERVER_PATH", "../../../third_party/scrcpy-server.jar"); + qputenv("QTSCRCPY_SERVER_PATH", "../../../third_party/scrcpy-server"); #endif //加载样式表 @@ -59,6 +64,8 @@ int main(int argc, char *argv[]) g_mainDlg = new Dialog; g_mainDlg->show(); + qInfo(QString("QtScrcpy %1 ").arg(QCoreApplication::applicationVersion()).toUtf8()); + int ret = a.exec(); #if defined(Q_OS_WIN32) || defined(Q_OS_OSX) diff --git a/README.md b/README.md index c45019e..b3e7647 100644 --- a/README.md +++ b/README.md @@ -174,11 +174,11 @@ Try to provide all the dependencies and make it easy to compile. 3. Open the project root directory all.pro with QtCreator 4. Compile and run -### Android (If you do not need to modify the requirements, you can use the built-in scrcpy-server.jar directly) +### Android (If you do not need to modify the requirements, you can use the built-in scrcpy-server directly) 1. Set up an Android development environment on the target platform 2. Open the server project in the project root directory using Android Studio 3. Build it -4. After compiling apk, rename it to scrcpy-server.jar and replace third_party/scrcpy-server.jar. +4. After compiling apk, rename it to scrcpy-server and replace third_party/scrcpy-server ## Licence Since it is based on scrcpy, respect its Licence diff --git a/README_zh.md b/README_zh.md index ff156dc..dcaaae2 100644 --- a/README_zh.md +++ b/README_zh.md @@ -182,12 +182,12 @@ Mac OS平台,你可以直接使用我编译好的可执行程序: 3. 使用QtCreator打开项目根目录all.pro 4. 编译,运行即可 -### Android端 (没有修改需求的话直接使用自带的scrcpy-server.jar即可) +### Android端 (没有修改需求的话直接使用自带的scrcpy-server即可) 1. 目标平台上搭建Android开发环境 2. 使用Android Studio打开项目根目录中的server项目 3. 第一次打开如果你没有对应版本的gradle会提示找不到gradle,是否升级gradle并创建,选择取消,取消后会弹出选择已有gradle的位置,同样取消即可(会自动下载) 4. 按需编辑代码即可,当然也可以不编辑 -4. 编译出apk以后改名为scrcpy-server.jar并替换third_party/scrcpy-server.jar即可 +4. 编译出apk以后改名为scrcpy-server并替换third_party/scrcpy-server即可 ## Licence 由于是复刻的scrcpy,尊重它的Licence diff --git a/docs/TODO.md b/docs/TODO.md index 282a69b..1dbda13 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -1,20 +1,15 @@ -最后同步scrcpy b91ecf52256da73f5c8dca04fb82c13ec826cbd7 +最后同步scrcpy 31bd95022bc525be42ca273d59a3211d964d278b # TODO ## 低优先级 - 中文输入(server需要改为apk,作为一个输入法,暂不实现)(或者有其他方式案件注入方式,例如搜狗手机输入法可以监听当前注入?) -- 鼠标事件相关系列 b35733edb6df2a00b6af9b1c98627d344c377963 - [跳过帧改为动态配置,而不是静态编译](https://github.com/Genymobile/scrcpy/commit/ebccb9f6cc111e8acfbe10d656cac5c1f1b744a0) - [单独线程统计帧率](https://github.com/Genymobile/scrcpy/commit/e2a272bf99ecf48fcb050177113f903b3fb323c4) - ui提供show touch设置 -- 隐藏手机皮肤开关 ## 中优先级 - [截屏保存为jpg](https://blog.csdn.net/m0_37684310/article/details/77950390) -- 版本号升级优化 -- linux打包以及版本号 - 自动打包脚本 -- 按键映射可配置 - 脚本 - 群控 - 配置文件 @@ -24,10 +19,9 @@ - 分辨率码率可自定义 ## 高优先级 -- 同步延迟优化 +- linux打包以及版本号 # BUG -1. 魅族手机提示cant open video stream,解决方法 https://dim.red/2019/03/03/scrcpy_usage/ # mark [ffmpeg编译参数详解](https://www.cnblogs.com/wainiwann/p/4204230.html) diff --git a/third_party/scrcpy-server b/third_party/scrcpy-server new file mode 100644 index 0000000000000000000000000000000000000000..640d0cfb10144ccad9cd78a16c9767e2e00a182f GIT binary patch literal 26142 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%0AD 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 literal 0 HcmV?d00001