diff --git a/taoyao-client-openharmony/taoyao/build-profile.json5 b/taoyao-client-openharmony/taoyao/build-profile.json5 index ee28ee5..cafbc80 100644 --- a/taoyao-client-openharmony/taoyao/build-profile.json5 +++ b/taoyao-client-openharmony/taoyao/build-profile.json5 @@ -13,15 +13,15 @@ { "name": "default", "material": { - "keyAlias" : "debugKey", - "signAlg" : "SHA256withECDSA", + "signAlg" : "SHA256withECDSA", + "keyAlias": "debugKey", + "keyPassword" : "0000001BEC83FE5E74E20C2BD84F2E7C3C00A1038029C6F2FE0121CA85487C1C334AFF202964F02D800AEC", + "storePassword": "0000001B2C10F7CA3C261A3B5F8DE65A4E13A65E37B6C298C3FD3C9A3ACCD5E10DF1F475F5370DF7996519", "profile" : "C:/Users/acgis/.ohos/config/openharmony/default_taoyao_RrmPaKOZ5zMCU4QlpK1kz_6UoyvfsA4RcQxqexSUJ_8=.p7b", "certpath" : "C:/Users/acgis/.ohos/config/openharmony/default_taoyao_RrmPaKOZ5zMCU4QlpK1kz_6UoyvfsA4RcQxqexSUJ_8=.cer", - "storeFile": "C:/Users/acgis/.ohos/config/openharmony/default_taoyao_RrmPaKOZ5zMCU4QlpK1kz_6UoyvfsA4RcQxqexSUJ_8=.p12", - "keyPassword" : "0000001BD55750CF879F40EE4EA1B96386BD83692A36E1776974D52D7439FEEEFCB8D2EC5C798FC7C815AE", - "storePassword": "0000001B2AC157AB2A1227E77D5E4925A0B59DE84E94B4D146D9C4DA5EAB030537941F0436A3C3E9F26424" + "storeFile": "C:/Users/acgis/.ohos/config/openharmony/default_taoyao_RrmPaKOZ5zMCU4QlpK1kz_6UoyvfsA4RcQxqexSUJ_8=.p12" } - }, + } ], }, "modules": [ diff --git a/taoyao-client-openharmony/taoyao/hvigor/hvigor-config.json5 b/taoyao-client-openharmony/taoyao/hvigor/hvigor-config.json5 index e4e048b..2da1b96 100644 --- a/taoyao-client-openharmony/taoyao/hvigor/hvigor-config.json5 +++ b/taoyao-client-openharmony/taoyao/hvigor/hvigor-config.json5 @@ -4,11 +4,6 @@ "@ohos/hvigor-ohos-plugin": "3.2.4" }, "execution": { - // "daemon" : true, - // "analyze" : "default", - // "parallel" : true, - // "typeCheck" : false, - // "incremental": true, }, "logging": { "level": "debug" diff --git a/taoyao-client-openharmony/taoyao/media/src/main/cpp/CMakeLists.txt b/taoyao-client-openharmony/taoyao/media/src/main/cpp/CMakeLists.txt index 9015f0d..f77aa9a 100644 --- a/taoyao-client-openharmony/taoyao/media/src/main/cpp/CMakeLists.txt +++ b/taoyao-client-openharmony/taoyao/media/src/main/cpp/CMakeLists.txt @@ -38,14 +38,15 @@ add_library( media/LocalClient.cpp media/RemoteClient.cpp media/MediaManager.cpp + media/VideoDecoder.cpp + media/VideoEncoder.cpp media/Player.cpp media/AudioPlayer.cpp media/VideoPlayer.cpp - media/VideoDecoder.cpp media/Capturer.cpp - media/VideoEncoder.cpp media/AudioCapturer.cpp - media/VideoCapturer.cpp + media/CameraCapturer.cpp + media/ScreenCapturer.cpp ) target_include_directories( @@ -83,6 +84,8 @@ target_link_libraries( libnative_media_venc.so libnative_media_core.so libnative_media_codecbase.so + # 屏幕录制 + libnative_avscreen_capture.so # libmediasoupclient mediasoupclient ) diff --git a/taoyao-client-openharmony/taoyao/media/src/main/cpp/include/Capturer.hpp b/taoyao-client-openharmony/taoyao/media/src/main/cpp/include/Capturer.hpp index 74502ad..1d1616c 100644 --- a/taoyao-client-openharmony/taoyao/media/src/main/cpp/include/Capturer.hpp +++ b/taoyao-client-openharmony/taoyao/media/src/main/cpp/include/Capturer.hpp @@ -20,7 +20,7 @@ #define TAOYAO_CAPTURER_HPP // 本地音频采集 -#define __TAOYAO_AUDIO_LOCAL__ true +#define __TAOYAO_AUDIO_LOCAL__ false // 本地视频采集 #define __TAOYAO_VIDEO_LOCAL__ true @@ -49,6 +49,10 @@ #include #include +#include +#include +#include + namespace acgist { /** @@ -114,7 +118,22 @@ public: /** * 视频采集器 */ -class VideoCapturer: public Capturer { +class VideoCapturer : public Capturer { + +public: + VideoCapturer() {}; + virtual ~VideoCapturer() override {}; + +public: + virtual bool start() override = 0; + virtual bool stop() override = 0; + +}; + +/** + * 相机采集器 + */ +class CameraCapturer : public VideoCapturer { public: // ================ OpenGL ES ================ @@ -153,8 +172,8 @@ public: Camera_OutputCapability* cameraOutputCapability = nullptr; public: - VideoCapturer(); - virtual ~VideoCapturer() override; + CameraCapturer(); + virtual ~CameraCapturer() override; public: // 加载OpenGL ES @@ -166,6 +185,24 @@ public: }; +/** + * 屏幕采集器 + */ +class ScreenCapturer : public VideoCapturer { + +public: + OH_AVScreenCapture* avScreenCapture = nullptr; + +public: + ScreenCapturer(); + virtual ~ScreenCapturer() override; + +public: + virtual bool start() override; + virtual bool stop() override; + +}; + } #endif // TAOYAO_CAPTURER_HPP diff --git a/taoyao-client-openharmony/taoyao/media/src/main/cpp/include/MediaManager.hpp b/taoyao-client-openharmony/taoyao/media/src/main/cpp/include/MediaManager.hpp index 6eda05b..2ac75d1 100644 --- a/taoyao-client-openharmony/taoyao/media/src/main/cpp/include/MediaManager.hpp +++ b/taoyao-client-openharmony/taoyao/media/src/main/cpp/include/MediaManager.hpp @@ -18,6 +18,9 @@ #include "api/peer_connection_interface.h" +#define TAOYAO_VIDEO_SOURCE_SCREEN true +#define TAOYAO_VIDEO_SOURCE_CAMERA false + namespace acgist { /** diff --git a/taoyao-client-openharmony/taoyao/media/src/main/cpp/media/AudioCapturer.cpp b/taoyao-client-openharmony/taoyao/media/src/main/cpp/media/AudioCapturer.cpp index 738124d..ab85924 100644 --- a/taoyao-client-openharmony/taoyao/media/src/main/cpp/media/AudioCapturer.cpp +++ b/taoyao-client-openharmony/taoyao/media/src/main/cpp/media/AudioCapturer.cpp @@ -76,12 +76,6 @@ static int32_t OnError(OH_AudioCapturer* capturer, void* userData, OH_AudioStrea return 0; } -#include -#include - - // TODO: 删除 - static std::ofstream outfile("/data/storage/el2/base/haps/media/files/audio.pcm"); - static int32_t OnReadData(OH_AudioCapturer* capturer, void* userData, void* buffer, int32_t length) { OH_LOG_DEBUG(LOG_APP, "音频帧数据采集回调:%{public}d", length); if(userData == nullptr) { @@ -96,7 +90,6 @@ static int32_t OnReadData(OH_AudioCapturer* capturer, void* userData, void* buff // 字节数量 * 8 / 位深 / 通道数量 size_t number_of_frames = length / 2; // size_t number_of_frames = length * 8 / 16 / 2; - outfile.write((char*) buffer, length); audioCapturer->source->OnData((uint16_t*) buffer, acgist::bitsPerSample, acgist::samplingRate, acgist::channelCount, number_of_frames); return 0; } diff --git a/taoyao-client-openharmony/taoyao/media/src/main/cpp/media/VideoCapturer.cpp b/taoyao-client-openharmony/taoyao/media/src/main/cpp/media/CameraCapturer.cpp similarity index 92% rename from taoyao-client-openharmony/taoyao/media/src/main/cpp/media/VideoCapturer.cpp rename to taoyao-client-openharmony/taoyao/media/src/main/cpp/media/CameraCapturer.cpp index 6142443..80c95dc 100644 --- a/taoyao-client-openharmony/taoyao/media/src/main/cpp/media/VideoCapturer.cpp +++ b/taoyao-client-openharmony/taoyao/media/src/main/cpp/media/CameraCapturer.cpp @@ -61,7 +61,7 @@ static void onFrame(void* context); // 检查EGL扩展 static bool CheckEglExtension(const char* extensions, const char* extension); -acgist::VideoCapturer::VideoCapturer() { +acgist::CameraCapturer::CameraCapturer() { initOpenGLES(); Camera_ErrorCode ret = OH_Camera_GetCameraManager(&this->cameraManager); TAOYAO_VIDEO_RET_LOG("配置相机管理:%{public}d", ret); @@ -108,7 +108,7 @@ acgist::VideoCapturer::VideoCapturer() { // OH_CaptureSession_SetZoomRatio(this->cameraCaptureSession, 0.5F); } -acgist::VideoCapturer::~VideoCapturer() { +acgist::CameraCapturer::~CameraCapturer() { releaseOpenGLES(); CaptureSession_Callbacks captureSession_Callbacks = { onSessionFocusStateChange, onSessionError }; Camera_ErrorCode ret = OH_CaptureSession_UnregisterCallback(this->cameraCaptureSession, &captureSession_Callbacks); @@ -148,7 +148,7 @@ acgist::VideoCapturer::~VideoCapturer() { TAOYAO_VIDEO_RET_LOG("释放相机管理:%{public}d", ret); } -bool acgist::VideoCapturer::start() { +bool acgist::CameraCapturer::start() { std::lock_guard videoLock(videoMutex); if (this->running) { return true; @@ -176,7 +176,7 @@ bool acgist::VideoCapturer::start() { return ret = Camera_ErrorCode::CAMERA_OK; } -bool acgist::VideoCapturer::stop() { +bool acgist::CameraCapturer::stop() { std::lock_guard videoLock(videoMutex); if (!this->running) { return true; @@ -204,7 +204,7 @@ bool acgist::VideoCapturer::stop() { return ret = Camera_ErrorCode::CAMERA_OK; } -void acgist::VideoCapturer::initOpenGLES() { +void acgist::CameraCapturer::initOpenGLES() { // EGL static const char* EGL_EXT_PLATFORM_WAYLAND = "EGL_EXT_platform_wayland"; static const char* EGL_KHR_PLATFORM_WAYLAND = "EGL_KHR_platform_wayland"; @@ -257,14 +257,16 @@ void acgist::VideoCapturer::initOpenGLES() { this->eglContext = eglCreateContext(this->eglDisplay, config, EGL_NO_CONTEXT, context_attribs); } const EGLint surfaceAttr[] = { - EGL_WIDTH, 1980, - EGL_HEIGHT, 1080, +// EGL_WIDTH, acgist::width, +// EGL_HEIGHT, acgist::height, EGL_LARGEST_PBUFFER, EGL_TRUE, EGL_NONE }; this->eglSurface = eglCreatePbufferSurface(this->eglDisplay, config, surfaceAttr); + // OH_NativeWindow_CreateNativeWindow(this->eglSurface); + eglMakeCurrent(this->eglDisplay, this->eglSurface, this->eglSurface, this->eglContext); // IMAGE WINDOW @@ -278,7 +280,7 @@ void acgist::VideoCapturer::initOpenGLES() { OH_LOG_INFO(LOG_APP, "视频采集SurfaceId:%{public}lld", this->surfaceId); } -void acgist::VideoCapturer::releaseOpenGLES() { +void acgist::CameraCapturer::releaseOpenGLES() { if(this->textureId != 0) { glDeleteTextures(this->textureSize, &this->textureId); this->textureId = 0; @@ -342,21 +344,20 @@ static void onSessionFocusStateChange(Camera_CaptureSession* session, Camera_Foc static void onFrame(void* context) { OH_LOG_DEBUG(LOG_APP, "视频帧数据采集回调:%{public}d", 1); - acgist::VideoCapturer* videoCapturer = (acgist::VideoCapturer*) context; -// OH_NativeImage_UpdateSurfaceImage(videoCapturer->nativeImage); + acgist::CameraCapturer* cameraCapturer = (acgist::CameraCapturer*) context; +// OH_NativeImage_UpdateSurfaceImage(cameraCapturer->nativeImage); // 更新内容到OpenGL纹理。 -uint32_t ret = OH_NativeImage_UpdateSurfaceImage(videoCapturer->nativeImage); +uint32_t ret = OH_NativeImage_UpdateSurfaceImage(cameraCapturer->nativeImage); if (ret != 0) { } // 获取最近调用OH_NativeImage_UpdateSurfaceImage的纹理图像的时间戳和变化矩阵。 -int64_t timeStamp = OH_NativeImage_GetTimestamp(videoCapturer->nativeImage); +int64_t timeStamp = OH_NativeImage_GetTimestamp(cameraCapturer->nativeImage); float matrix[16]; -ret = OH_NativeImage_GetTransformMatrix(videoCapturer->nativeImage, matrix); +ret = OH_NativeImage_GetTransformMatrix(cameraCapturer->nativeImage, matrix); if (ret != 0) { } - // 对update绑定到对应textureId的纹理做对应的opengl后处理后,将纹理上屏 -EGLBoolean eglRet = eglSwapBuffers(videoCapturer->eglDisplay, videoCapturer->eglSurface); +EGLBoolean eglRet = eglSwapBuffers(cameraCapturer->eglDisplay, cameraCapturer->eglSurface); if (eglRet == EGL_FALSE) { } //HWTEST_F(NativeImageTest, OHNativeImageSetOnFrameAvailableListener001, Function | MediumTest | Level1) @@ -396,7 +397,7 @@ if (eglRet == EGL_FALSE) { // ret = OH_NativeImage_UpdateSurfaceImage(image); // ASSERT_EQ(ret, SURFACE_ERROR_OK); //} -// OHNativeWindow* nativeWindow = OH_NativeImage_AcquireNativeWindow(videoCapturer->nativeImage); +// OHNativeWindow* nativeWindow = OH_NativeImage_AcquireNativeWindow(cameraCapturer->nativeImage); // int code = SET_BUFFER_GEOMETRY; // int32_t width = 800; // int32_t height = 600; @@ -411,30 +412,30 @@ if (eglRet == EGL_FALSE) { //// 通过OH_NativeWindow_NativeWindowFlushBuffer 提交给消费者使用,例如:显示在屏幕上。 //OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow, buffer, fenceFd, region); // // 更新内容到OpenGL纹理。 -// ret = OH_NativeImage_UpdateSurfaceImage(videoCapturer->nativeImage); +// ret = OH_NativeImage_UpdateSurfaceImage(cameraCapturer->nativeImage); //if (ret != 0) { //} //// 获取最近调用OH_NativeImage_UpdateSurfaceImage的纹理图像的时间戳和变化矩阵。 -//int64_t timeStamp = OH_NativeImage_GetTimestamp(videoCapturer->nativeImage); +//int64_t timeStamp = OH_NativeImage_GetTimestamp(cameraCapturer->nativeImage); //float matrix[16]; -//ret = OH_NativeImage_GetTransformMatrix(videoCapturer->nativeImage, matrix); +//ret = OH_NativeImage_GetTransformMatrix(cameraCapturer->nativeImage, matrix); //if (ret != 0) { //} // //// 对update绑定到对应textureId的纹理做对应的opengl后处理后,将纹理上屏 -//EGLBoolean eglRet = eglSwapBuffers(videoCapturer->eglDisplay, videoCapturer->eglSurface); +//EGLBoolean eglRet = eglSwapBuffers(cameraCapturer->eglDisplay, cameraCapturer->eglSurface); //if (eglRet == EGL_FALSE) { //} -// eglMakeCurrent(videoCapturer->eglDisplay, videoCapturer->eglSurface, videoCapturer->eglSurface, videoCapturer->eglContext); -// OH_NativeImage_UpdateSurfaceImage(videoCapturer->nativeImage); -// OH_NativeImage_GetTimestamp(videoCapturer->nativeImage); +// eglMakeCurrent(cameraCapturer->eglDisplay, cameraCapturer->eglSurface, cameraCapturer->eglSurface, cameraCapturer->eglContext); +// OH_NativeImage_UpdateSurfaceImage(cameraCapturer->nativeImage); +// OH_NativeImage_GetTimestamp(cameraCapturer->nativeImage); // float matrix[16]; -// OH_NativeImage_GetTransformMatrix(videoCapturer->nativeImage, matrix); -// eglSwapBuffers(videoCapturer->eglDisplay, videoCapturer->eglSurface); +// OH_NativeImage_GetTransformMatrix(cameraCapturer->nativeImage, matrix); +// eglSwapBuffers(cameraCapturer->eglDisplay, cameraCapturer->eglSurface); // char* chars = new char[1024]; -// eglQueryNativePixmapNV(videoCapturer->eglDisplay, videoCapturer->eglSurface, &pixmap); -// EGLBoolean ret = eglCopyBuffers(videoCapturer->eglDisplay, videoCapturer->eglSurface, (EGLNativePixmapType) chars); +// eglQueryNativePixmapNV(cameraCapturer->eglDisplay, cameraCapturer->eglSurface, &pixmap); +// EGLBoolean ret = eglCopyBuffers(cameraCapturer->eglDisplay, cameraCapturer->eglSurface, (EGLNativePixmapType) chars); // char buffer[1024]; // glReadPixels(0, 0, 10, 10, GL_RGBA, GL_UNSIGNED_BYTE, buffer); // OH_LOG_DEBUG(LOG_APP, "视频帧数据采集回调读取:%{public}d", ret); @@ -447,7 +448,7 @@ if (eglRet == EGL_FALSE) { // webrtc::VideoFrame::Builder builder; // webrtc::VideoFrame videoFrame = // builder.set_timestamp_ms(rtc::TimeMillis()).set_video_frame_buffer(videoFrameBuffer).build(); -// for (auto iterator = videoCapturer->map.begin(); iterator != videoCapturer->map.end(); ++iterator) { +// for (auto iterator = cameraCapturer->map.begin(); iterator != cameraCapturer->map.end(); ++iterator) { // iterator->second->OnFrame(videoFrame); // } // // TODO: 释放webrtc diff --git a/taoyao-client-openharmony/taoyao/media/src/main/cpp/media/LocalClient.cpp b/taoyao-client-openharmony/taoyao/media/src/main/cpp/media/LocalClient.cpp index 90a0b67..29a8119 100644 --- a/taoyao-client-openharmony/taoyao/media/src/main/cpp/media/LocalClient.cpp +++ b/taoyao-client-openharmony/taoyao/media/src/main/cpp/media/LocalClient.cpp @@ -2,8 +2,8 @@ acgist::LocalClient::LocalClient(acgist::MediaManager* mediaManager) : acgist::RoomClient(mediaManager) { this->mediaManager->newLocalClient(); - this->audioTrack = this->mediaManager->getAudioTrack(); - // this->videoTrack = this->mediaManager->getVideoTrack(); + // this->audioTrack = this->mediaManager->getAudioTrack(); + this->videoTrack = this->mediaManager->getVideoTrack(); } acgist::LocalClient::~LocalClient() { diff --git a/taoyao-client-openharmony/taoyao/media/src/main/cpp/media/MediaManager.cpp b/taoyao-client-openharmony/taoyao/media/src/main/cpp/media/MediaManager.cpp index 63bd43a..bc4d16d 100644 --- a/taoyao-client-openharmony/taoyao/media/src/main/cpp/media/MediaManager.cpp +++ b/taoyao-client-openharmony/taoyao/media/src/main/cpp/media/MediaManager.cpp @@ -109,8 +109,8 @@ int acgist::MediaManager::releaseLocalClient() { } bool acgist::MediaManager::startCapture() { - this->startAudioCapture(); - // this->startVideoCapture(); + // this->startAudioCapture(); + this->startVideoCapture(); return true; } @@ -130,10 +130,10 @@ bool acgist::MediaManager::startAudioCapture() { if(this->audioTrackSource == nullptr) { OH_LOG_INFO(LOG_APP, "设置音频来源"); cricket::AudioOptions options; - options.highpass_filter = true; - options.auto_gain_control = true; - options.echo_cancellation = true; - options.noise_suppression = true; +// options.highpass_filter = true; +// options.auto_gain_control = true; +// options.echo_cancellation = true; +// options.noise_suppression = true; this->audioTrackSource = this->peerConnectionFactory->CreateAudioSource(options); } #endif @@ -143,7 +143,14 @@ bool acgist::MediaManager::startAudioCapture() { bool acgist::MediaManager::startVideoCapture() { if(this->videoCapturer == nullptr) { OH_LOG_INFO(LOG_APP, "开始视频采集"); - this->videoCapturer = new acgist::VideoCapturer(); + #if TAOYAO_VIDEO_SOURCE_SCREEN + OH_LOG_INFO(LOG_APP, "开始屏幕采集"); + this->videoCapturer = new acgist::ScreenCapturer(); + #endif + #if TAOYAO_VIDEO_SOURCE_CAMERA + OH_LOG_INFO(LOG_APP, "开始相机采集"); + this->videoCapturer = new acgist::CameraCapturer(); + #endif this->videoCapturer->start(); } if(this->videoTrackSource == nullptr) { diff --git a/taoyao-client-openharmony/taoyao/media/src/main/cpp/media/Room.cpp b/taoyao-client-openharmony/taoyao/media/src/main/cpp/media/Room.cpp index 9ec2382..a23b0e8 100644 --- a/taoyao-client-openharmony/taoyao/media/src/main/cpp/media/Room.cpp +++ b/taoyao-client-openharmony/taoyao/media/src/main/cpp/media/Room.cpp @@ -118,10 +118,10 @@ int acgist::Room::produceMedia() { this->createRecvTransport(); } if(this->audioProduce) { - this->produceAudio(); + // this->produceAudio(); } if(this->videoProduce) { - // this->produceVideo(); + this->produceVideo(); } return 0; } diff --git a/taoyao-client-openharmony/taoyao/media/src/main/cpp/media/ScreenCapturer.cpp b/taoyao-client-openharmony/taoyao/media/src/main/cpp/media/ScreenCapturer.cpp new file mode 100644 index 0000000..70b4d4a --- /dev/null +++ b/taoyao-client-openharmony/taoyao/media/src/main/cpp/media/ScreenCapturer.cpp @@ -0,0 +1,107 @@ +#include "../include/Capturer.hpp" + +#include + +#include "api/video/nv12_buffer.h" +#include "api/video/i420_buffer.h" + +// 没法 +static acgist::ScreenCapturer* screenCapturer = nullptr; + +static void OnError(OH_AVScreenCapture* capture, int32_t errorCode) { + OH_LOG_ERROR(LOG_APP, "屏幕采集异常:%{public}d", errorCode); +} + +static void OnAudioBufferAvailable(OH_AVScreenCapture* capture, bool isReady, OH_AudioCaptureSourceType type) { + // OH_LOG_DEBUG(LOG_APP, "屏幕采集音频数据帧"); + if (isReady) { + OH_AudioBuffer* buffer = new OH_AudioBuffer; + int32_t ret = OH_AVScreenCapture_AcquireAudioBuffer(capture, &buffer, type); + (void) buffer->buf; + (void) buffer->size; + (void) buffer->timestamp; + delete buffer; + buffer = nullptr; + OH_AVScreenCapture_ReleaseAudioBuffer(capture, type); + } +} + +static void OnVideoBufferAvailable(OH_AVScreenCapture* capture, bool isReady) { + OH_LOG_DEBUG(LOG_APP, "屏幕采集视频数据帧"); + if (isReady) { + int32_t fence = 0; + int64_t timestamp = 0; + OH_Rect damage; + OH_NativeBuffer* buffer = OH_AVScreenCapture_AcquireVideoBuffer(capture, &fence, ×tamp, &damage); + void* virAddr = nullptr; + OH_NativeBuffer_Map(buffer, &virAddr); + OH_NativeBuffer_Config config; + OH_NativeBuffer_GetConfig(buffer, &config); + // rtc::scoped_refptr videoFrameBuffer = webrtc::I420Buffer::Copy(config.width, config.height, (uint8_t*) virAddr, 0, (uint8_t*) virAddr, 0, (uint8_t*) virAddr, 0); + // webrtc::VideoFrame::Builder builder; + // webrtc::VideoFrame videoFrame = builder.set_timestamp_ms(timestamp).set_video_frame_buffer(videoFrameBuffer).build(); + // screenCapturer->source->OnData(videoFrame); + OH_NativeBuffer_Unmap(buffer); + OH_AVScreenCapture_ReleaseVideoBuffer(capture); + } +} + +acgist::ScreenCapturer::ScreenCapturer() { + this->avScreenCapture = OH_AVScreenCapture_Create(); + OH_AVScreenCaptureCallback callback; + callback.onError = OnError; + callback.onAudioBufferAvailable = OnAudioBufferAvailable; + callback.onVideoBufferAvailable = OnVideoBufferAvailable; + OH_AVScreenCapture_SetCallback(this->avScreenCapture, callback); + OH_AudioCaptureInfo audioCaptureInfo = { + .audioSampleRate = acgist::samplingRate, + .audioChannels = acgist::channelCount, + .audioSource = OH_MIC + }; + OH_AudioInfo audioInfo = { + .micCapInfo = audioCaptureInfo, + }; + OH_VideoCaptureInfo videoCaptureInfo = { + // .videoFrameWidth = static_cast(acgist::width), + // .videoFrameHeight = static_cast(acgist::height), + .videoFrameWidth = static_cast(800), + .videoFrameHeight = static_cast(1280), + .videoSource = OH_VIDEO_SOURCE_SURFACE_RGBA + // .videoSource = OH_VIDEO_SOURCE_SURFACE_YUV + }; + // OH_VideoEncInfo videoEncInfo = { + // .videoCodec = OH_VideoCodecFormat::OH_H264, + // .videoBitrate = acgist::bitrate, + // .videoFrameRate = acgist::frameRate + // }; + OH_VideoInfo videoInfo = { + .videoCapInfo = videoCaptureInfo, + // .videoEncInfo = videoEncInfo + }; + OH_AVScreenCaptureConfig config = { + .captureMode = OH_CAPTURE_HOME_SCREEN, + .dataType = OH_ORIGINAL_STREAM, + .audioInfo = audioInfo, + .videoInfo = videoInfo, + }; + OH_AVScreenCapture_Init(this->avScreenCapture, config); + OH_AVScreenCapture_SetMicrophoneEnabled(this->avScreenCapture, false); + screenCapturer = this; +} + +bool acgist::ScreenCapturer::start() { + OH_LOG_INFO(LOG_APP, "打开屏幕采集"); + OH_AVScreenCapture_StartScreenCapture(this->avScreenCapture); + return true; +} + +bool acgist::ScreenCapturer::stop() { + OH_LOG_INFO(LOG_APP, "关闭屏幕采集"); + OH_AVScreenCapture_StopScreenCapture(this->avScreenCapture); + return true; +} + +acgist::ScreenCapturer::~ScreenCapturer() { + OH_AVScreenCapture_Release(this->avScreenCapture); + this->avScreenCapture = nullptr; +} diff --git a/taoyao-client-openharmony/taoyao/media/src/main/cpp/media/Signal.cpp b/taoyao-client-openharmony/taoyao/media/src/main/cpp/media/Signal.cpp index 3527ebc..a2e3181 100644 --- a/taoyao-client-openharmony/taoyao/media/src/main/cpp/media/Signal.cpp +++ b/taoyao-client-openharmony/taoyao/media/src/main/cpp/media/Signal.cpp @@ -2,11 +2,11 @@ namespace acgist { -uint32_t width = 720; +uint32_t width = 640; uint32_t height = 480; uint64_t bitrate = 3'000'000L; uint32_t iFrameInterval = 5'000; -double frameRate = 30.0; +double frameRate = 10.0; int32_t samplingRate = 48'000; int32_t channelCount = 2; int32_t bitsPerSample = 16; diff --git a/taoyao-client-openharmony/taoyao/media/src/main/ets/pages/Index.ets b/taoyao-client-openharmony/taoyao/media/src/main/ets/pages/Index.ets index f0d034f..4939df9 100644 --- a/taoyao-client-openharmony/taoyao/media/src/main/ets/pages/Index.ets +++ b/taoyao-client-openharmony/taoyao/media/src/main/ets/pages/Index.ets @@ -13,6 +13,8 @@ const permissions: Array = [ "ohos.permission.MICROPHONE", "ohos.permission.READ_MEDIA", "ohos.permission.WRITE_MEDIA", + "ohos.permission.CAPTURE_SCREEN", + "ohos.permission.CAPTURE_VOICE_DOWNLINK_AUDIO", ]; function reqPermissionsFromUser(permissions: Array, context: common.UIAbilityContext) { diff --git a/taoyao-client-openharmony/taoyao/media/src/main/module.json5 b/taoyao-client-openharmony/taoyao/media/src/main/module.json5 index 7f722c4..4d61307 100644 --- a/taoyao-client-openharmony/taoyao/media/src/main/module.json5 +++ b/taoyao-client-openharmony/taoyao/media/src/main/module.json5 @@ -38,37 +38,47 @@ "name": "ohos.permission.CAMERA", "reason": "$string:app_name", "usedScene": { - "when": "inuse" + "when": "inuse", + "abilities": [ "EntryAbility" ] } }, { "name": "ohos.permission.INTERNET", "reason": "$string:app_name", - "usedScene": { - "when": "always" - } }, { "name": "ohos.permission.MICROPHONE", "reason": "$string:app_name", "usedScene": { - "when": "inuse" + "when": "inuse", + "abilities": [ "EntryAbility" ] } }, { "name": "ohos.permission.READ_MEDIA", "reason": "$string:app_name", "usedScene": { - "when": "always" + "when": "always", + "abilities": [ "EntryAbility" ] } }, { "name": "ohos.permission.WRITE_MEDIA", "reason": "$string:app_name", "usedScene": { - "when": "always" + "when": "always", + "abilities": [ "EntryAbility" ] } }, + // 🤡🤡🤡🤡 + { + "name": "ohos.permission.CAPTURE_SCREEN", + "reason": "$string:app_name", + }, + { + "name": "ohos.permission.CAPTURE_VOICE_DOWNLINK_AUDIO", + "reason": "$string:app_name", + }, ] } }