From 1d63886238053aea3d55b77c5d142e4fab1837d0 Mon Sep 17 00:00:00 2001 From: Ryan <865833921@qq.com> Date: Tue, 8 Jul 2025 15:25:35 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E5=90=8C=E6=BA=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- entry/src/main/cpp/capbilities/Demuxer.cpp | 7 ++++-- entry/src/main/cpp/capbilities/Muxer.cpp | 6 +++-- .../src/main/cpp/capbilities/VideoDecoder.cpp | 20 ++++------------ .../src/main/cpp/capbilities/VideoEncoder.cpp | 16 ++++++------- .../main/cpp/capbilities/include/Demuxer.h | 1 - .../cpp/capbilities/include/VideoEncoder.h | 1 - entry/src/main/cpp/common/SampleCallback.cpp | 2 ++ .../cpp/sample/transcoding/Transcoding.cpp | 24 ++++++++++++++----- entry/src/main/ets/pages/VideoPlayer.ets | 6 +---- .../main/resources/base/element/string.json | 4 ++++ .../main/resources/en_US/element/string.json | 4 ++++ .../main/resources/zh_CN/element/string.json | 4 ++++ 12 files changed, 53 insertions(+), 42 deletions(-) diff --git a/entry/src/main/cpp/capbilities/Demuxer.cpp b/entry/src/main/cpp/capbilities/Demuxer.cpp index 93de06a..1f2f928 100644 --- a/entry/src/main/cpp/capbilities/Demuxer.cpp +++ b/entry/src/main/cpp/capbilities/Demuxer.cpp @@ -20,6 +20,7 @@ Demuxer::~Demuxer() { Release(); } +// [Start create_demuxer] int32_t Demuxer::Create(SampleInfo &info) { source_ = OH_AVSource_CreateWithFD(info.inputFd, info.inputFileOffset, info.inputFileSize); CHECK_AND_RETURN_RET_LOG(source_ != nullptr, AVCODEC_SAMPLE_ERR_ERROR, @@ -37,6 +38,7 @@ int32_t Demuxer::Create(SampleInfo &info) { return AVCODEC_SAMPLE_ERR_OK; } +// [End create_demuxer] int32_t Demuxer::ReadSample(int32_t trackId, OH_AVBuffer *buffer, OH_AVCodecBufferAttr &attr) { CHECK_AND_RETURN_RET_LOG(demuxer_ != nullptr, AVCODEC_SAMPLE_ERR_ERROR, "Demuxer is null"); @@ -59,6 +61,7 @@ int32_t Demuxer::Release() { return AVCODEC_SAMPLE_ERR_OK; } +// [Start get_track_info] int32_t Demuxer::GetTrackInfo(std::shared_ptr sourceFormat, SampleInfo &info) { int32_t trackCount = 0; OH_AVFormat_GetIntValue(sourceFormat.get(), OH_MD_KEY_TRACK_COUNT, &trackCount); @@ -121,6 +124,6 @@ int32_t Demuxer::GetTrackInfo(std::shared_ptr sourceFormat, SampleI return AVCODEC_SAMPLE_ERR_OK; } +// [End get_track_info] -int32_t Demuxer::GetVideoTrackId() { return videoTrackId_; } -int32_t Demuxer::GetAudioTrackId() { return audioTrackId_; } \ No newline at end of file +int32_t Demuxer::GetVideoTrackId() { return videoTrackId_; } \ No newline at end of file diff --git a/entry/src/main/cpp/capbilities/Muxer.cpp b/entry/src/main/cpp/capbilities/Muxer.cpp index 167992f..a4dd17c 100644 --- a/entry/src/main/cpp/capbilities/Muxer.cpp +++ b/entry/src/main/cpp/capbilities/Muxer.cpp @@ -26,7 +26,6 @@ constexpr int32_t SAMPLE_RATE = 16000; Muxer::~Muxer() { Release(); } -// [Start format_path] // Create an encapsulator instance object and set the encapsulation format to mp4 int32_t Muxer::Create(int32_t fd) { muxer_ = OH_AVMuxer_Create(fd, AV_OUTPUT_FORMAT_MPEG_4); @@ -34,6 +33,7 @@ int32_t Muxer::Create(int32_t fd) { return AVCODEC_SAMPLE_ERR_OK; } +// [Start config_muxer] int32_t Muxer::Config(SampleInfo &sampleInfo) { CHECK_AND_RETURN_RET_LOG(muxer_ != nullptr, AVCODEC_SAMPLE_ERR_ERROR, "Muxer is null"); OH_AVFormat *formatVideo = @@ -59,7 +59,7 @@ int32_t Muxer::Config(SampleInfo &sampleInfo) { CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, AVCODEC_SAMPLE_ERR_ERROR, "AddTrack failed"); return AVCODEC_SAMPLE_ERR_OK; } -// [End format_path] +// [End config_muxer] int32_t Muxer::Start() { CHECK_AND_RETURN_RET_LOG(muxer_ != nullptr, AVCODEC_SAMPLE_ERR_ERROR, "Muxer is null"); @@ -69,6 +69,7 @@ int32_t Muxer::Start() { return AVCODEC_SAMPLE_ERR_OK; } +// [Start write_sample] int32_t Muxer::WriteSample(int32_t trackId, OH_AVBuffer *buffer, OH_AVCodecBufferAttr &attr){ std::lock_guard lock(writeMutex_); @@ -82,6 +83,7 @@ int32_t Muxer::WriteSample(int32_t trackId, OH_AVBuffer *buffer, OH_AVCodecBuffe CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, AVCODEC_SAMPLE_ERR_ERROR, "Write sample failed"); return AVCODEC_SAMPLE_ERR_OK; } +// [End write_sample] int32_t Muxer::Release() { if (muxer_ != nullptr) { diff --git a/entry/src/main/cpp/capbilities/VideoDecoder.cpp b/entry/src/main/cpp/capbilities/VideoDecoder.cpp index f832255..8adea4e 100644 --- a/entry/src/main/cpp/capbilities/VideoDecoder.cpp +++ b/entry/src/main/cpp/capbilities/VideoDecoder.cpp @@ -32,6 +32,7 @@ int32_t VideoDecoder::Create(const std::string &videoCodecMime) { return AVCODEC_SAMPLE_ERR_OK; } +// [Start config_decoder] // Setting the callback function int32_t VideoDecoder::SetCallback(CodecUserData *codecUserData) { int32_t ret = AV_ERR_OK; @@ -45,7 +46,6 @@ int32_t VideoDecoder::SetCallback(CodecUserData *codecUserData) { } int32_t VideoDecoder::Configure(const SampleInfo &sampleInfo) { - // [StartExclude set_decoder] OH_AVFormat *format = OH_AVFormat_Create(); CHECK_AND_RETURN_RET_LOG(format != nullptr, AVCODEC_SAMPLE_ERR_ERROR, "AVFormat create failed"); @@ -59,31 +59,20 @@ int32_t VideoDecoder::Configure(const SampleInfo &sampleInfo) { AVCODEC_SAMPLE_LOGI("%{public}d*%{public}d, %{public}.1ffps", sampleInfo.videoWidth, sampleInfo.videoHeight, sampleInfo.frameRate); AVCODEC_SAMPLE_LOGI("====== VideoDecoder config ======"); - // [EndExclude set_decoder] int ret = OH_VideoDecoder_Configure(decoder_, format); - // [StartExclude set_decoder] OH_AVFormat_Destroy(format); format = nullptr; CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, AVCODEC_SAMPLE_ERR_ERROR, "Config failed, ret: %{public}d", ret); return AVCODEC_SAMPLE_ERR_OK; - // [EndExclude set_decoder] } - int32_t VideoDecoder::Config(const SampleInfo &sampleInfo, CodecUserData *codecUserData) { - // [StartExclude decoder_ready] CHECK_AND_RETURN_RET_LOG(decoder_ != nullptr, AVCODEC_SAMPLE_ERR_ERROR, "Decoder is null"); CHECK_AND_RETURN_RET_LOG(codecUserData != nullptr, AVCODEC_SAMPLE_ERR_ERROR, "Invalid param: codecUserData"); // Configure video decoder int32_t ret = Configure(sampleInfo); CHECK_AND_RETURN_RET_LOG(ret == AVCODEC_SAMPLE_ERR_OK, AVCODEC_SAMPLE_ERR_ERROR, "Configure failed"); - // SetSurface from video decoder -// if (sampleInfo.window != nullptr) { -// int ret = OH_VideoDecoder_SetSurface(decoder_, sampleInfo.window); -// CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK && sampleInfo.window, AVCODEC_SAMPLE_ERR_ERROR, -// "Set surface failed, ret: %{public}d", ret); -// } // SetCallback for video decoder ret = SetCallback(codecUserData); @@ -91,13 +80,12 @@ int32_t VideoDecoder::Config(const SampleInfo &sampleInfo, CodecUserData *codecU "Set callback failed, ret: %{public}d", ret); // Prepare video decoder - { - int ret = OH_VideoDecoder_Prepare(decoder_); - CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, AVCODEC_SAMPLE_ERR_ERROR, "Prepare failed, ret: %{public}d", ret); - } + ret = OH_VideoDecoder_Prepare(decoder_); + CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, AVCODEC_SAMPLE_ERR_ERROR, "Prepare failed, ret: %{public}d", ret); return AVCODEC_SAMPLE_ERR_OK; } +// [End config_decoder] int32_t VideoDecoder::Start() { CHECK_AND_RETURN_RET_LOG(decoder_ != nullptr, AVCODEC_SAMPLE_ERR_ERROR, "Decoder is null"); diff --git a/entry/src/main/cpp/capbilities/VideoEncoder.cpp b/entry/src/main/cpp/capbilities/VideoEncoder.cpp index bec3645..f06ea93 100644 --- a/entry/src/main/cpp/capbilities/VideoEncoder.cpp +++ b/entry/src/main/cpp/capbilities/VideoEncoder.cpp @@ -29,6 +29,7 @@ int32_t VideoEncoder::Create(const std::string &videoCodecMime) { } // [End encoder_initialization] +// [Start config_encoder] int32_t VideoEncoder::Config(SampleInfo &sampleInfo, CodecUserData *codecUserData) { CHECK_AND_RETURN_RET_LOG(encoder_ != nullptr, AVCODEC_SAMPLE_ERR_ERROR, "Encoder is null"); CHECK_AND_RETURN_RET_LOG(codecUserData != nullptr, AVCODEC_SAMPLE_ERR_ERROR, "Invalid param: codecUserData"); @@ -49,6 +50,7 @@ int32_t VideoEncoder::Config(SampleInfo &sampleInfo, CodecUserData *codecUserDat return AVCODEC_SAMPLE_ERR_OK; } +// [StartExclude config_encoder] // [Start start_encoder] // Start Encoder int32_t VideoEncoder::Start() { @@ -107,11 +109,9 @@ int32_t VideoEncoder::SetCallback(CodecUserData *codecUserData) { return AVCODEC_SAMPLE_ERR_OK; } +// [EndExclude config_encoder] -// Camera+AVCodec -// [Start camera_AVCodec] int32_t VideoEncoder::Configure(const SampleInfo &sampleInfo) { - // [StartExclude camera_AVCodec] OH_AVFormat *format = OH_AVFormat_Create(); CHECK_AND_RETURN_RET_LOG(format != nullptr, AVCODEC_SAMPLE_ERR_ERROR, "AVFormat create failed"); @@ -122,7 +122,6 @@ int32_t VideoEncoder::Configure(const SampleInfo &sampleInfo) { OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODE_BITRATE_MODE, sampleInfo.bitrateMode); OH_AVFormat_SetLongValue(format, OH_MD_KEY_BITRATE, sampleInfo.outputBitrate); OH_AVFormat_SetIntValue(format, OH_MD_KEY_PROFILE, sampleInfo.hevcProfile); - // [EndExclude camera_AVCodec] // Setting HDRVivid-related parameters if (sampleInfo.isHDRVivid) { OH_AVFormat_SetIntValue(format, OH_MD_KEY_I_FRAME_INTERVAL, sampleInfo.iFrameInterval); @@ -131,7 +130,6 @@ int32_t VideoEncoder::Configure(const SampleInfo &sampleInfo) { OH_AVFormat_SetIntValue(format, OH_MD_KEY_TRANSFER_CHARACTERISTICS, sampleInfo.transfer); OH_AVFormat_SetIntValue(format, OH_MD_KEY_MATRIX_COEFFICIENTS, sampleInfo.matrix); } - // [StartExclude camera_AVCodec] AVCODEC_SAMPLE_LOGI("====== VideoEncoder config ======"); AVCODEC_SAMPLE_LOGI("%{public}d*%{public}d, %{public}.1ffps", sampleInfo.videoWidth, sampleInfo.videoHeight, sampleInfo.frameRate); @@ -142,18 +140,18 @@ int32_t VideoEncoder::Configure(const SampleInfo &sampleInfo) { // Setting the Encoder int ret = OH_VideoEncoder_Configure(encoder_, format); - // [End set_encoder] OH_AVFormat_Destroy(format); format = nullptr; CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, AVCODEC_SAMPLE_ERR_ERROR, "Config failed, ret: %{public}d", ret); return AVCODEC_SAMPLE_ERR_OK; - // [EndExclude camera_AVCodec] } -// [End camera_AVCodec] +// [End config_encoder] +// [End push_input_buffer] int32_t VideoEncoder::PushInputBuffer(CodecBufferInfo &info) { CHECK_AND_RETURN_RET_LOG(encoder_ != nullptr, AVCODEC_SAMPLE_ERR_ERROR, "Decoder is null"); int32_t ret = OH_VideoEncoder_PushInputBuffer(encoder_, info.bufferIndex); CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, AVCODEC_SAMPLE_ERR_ERROR, "Push input data failed"); return AVCODEC_SAMPLE_ERR_OK; -} \ No newline at end of file +} +// [End push_input_buffer] \ No newline at end of file diff --git a/entry/src/main/cpp/capbilities/include/Demuxer.h b/entry/src/main/cpp/capbilities/include/Demuxer.h index 26fcd6c..96adf51 100644 --- a/entry/src/main/cpp/capbilities/include/Demuxer.h +++ b/entry/src/main/cpp/capbilities/include/Demuxer.h @@ -31,7 +31,6 @@ public: int32_t ReadSample(int32_t trackId, OH_AVBuffer *buffer, OH_AVCodecBufferAttr &attr); int32_t Release(); int32_t GetVideoTrackId(); - int32_t GetAudioTrackId(); private: int32_t GetTrackInfo(std::shared_ptr sourceFormat, SampleInfo &info); diff --git a/entry/src/main/cpp/capbilities/include/VideoEncoder.h b/entry/src/main/cpp/capbilities/include/VideoEncoder.h index 4d511d3..287f551 100644 --- a/entry/src/main/cpp/capbilities/include/VideoEncoder.h +++ b/entry/src/main/cpp/capbilities/include/VideoEncoder.h @@ -42,7 +42,6 @@ public: private: int32_t SetCallback(CodecUserData *codecUserData); int32_t Configure(const SampleInfo &sampleInfo); - int32_t GetSurface(SampleInfo &sampleInfo); bool isAVBufferMode_ = false; OH_AVCodec *encoder_ = nullptr; }; diff --git a/entry/src/main/cpp/common/SampleCallback.cpp b/entry/src/main/cpp/common/SampleCallback.cpp index b90e5a2..99a46e1 100644 --- a/entry/src/main/cpp/common/SampleCallback.cpp +++ b/entry/src/main/cpp/common/SampleCallback.cpp @@ -43,6 +43,7 @@ void SampleCallback::OnNeedInputBuffer(OH_AVCodec *codec, uint32_t index, OH_AVB codecUserData->inputCond.notify_all(); } +// [Start new_output_buffer] void SampleCallback::OnNewOutputBuffer(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *buffer, void *userData) { if (userData == nullptr) { return; @@ -61,6 +62,7 @@ void SampleCallback::OnNewOutputBuffer(OH_AVCodec *codec, uint32_t index, OH_AVB codecUserData->outputBufferInfoQueue.emplace(index, buffer); codecUserData->outputCond.notify_all(); } +// [End new_output_buffer] void SampleCallback::EncOnNeedInputBuffer(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *buffer, void *userData) { if (userData == nullptr) { diff --git a/entry/src/main/cpp/sample/transcoding/Transcoding.cpp b/entry/src/main/cpp/sample/transcoding/Transcoding.cpp index b4c1768..5111594 100644 --- a/entry/src/main/cpp/sample/transcoding/Transcoding.cpp +++ b/entry/src/main/cpp/sample/transcoding/Transcoding.cpp @@ -70,6 +70,7 @@ int32_t Transcoding::Init(SampleInfo &sampleInfo) { return AVCODEC_SAMPLE_ERR_OK; } +// [Start init_decoder] int32_t Transcoding::InitDecoder() { CHECK_AND_RETURN_RET_LOG(!isStarted_, AVCODEC_SAMPLE_ERR_ERROR, "Already started."); CHECK_AND_RETURN_RET_LOG(demuxer_ == nullptr && videoDecoder_ == nullptr, @@ -88,6 +89,7 @@ int32_t Transcoding::InitDecoder() { } return ret; } +// [End init_decoder] int32_t Transcoding::CreateVideoEncoder() { int32_t ret = videoEncoder_->Create(sampleInfo_.outputVideoCodecMime); @@ -100,6 +102,7 @@ int32_t Transcoding::CreateVideoEncoder() { return AVCODEC_SAMPLE_ERR_OK; } +// [Start init_encoder] int32_t Transcoding::InitEncoder() { CHECK_AND_RETURN_RET_LOG(!isStarted_, AVCODEC_SAMPLE_ERR_ERROR, "Already started."); CHECK_AND_RETURN_RET_LOG(muxer_ == nullptr && videoEncoder_ == nullptr, @@ -121,8 +124,9 @@ int32_t Transcoding::InitEncoder() { AVCODEC_SAMPLE_LOGI("Succeed"); return AVCODEC_SAMPLE_ERR_OK; } +// [End init_encoder] - +// [Start start_transcoding] int32_t Transcoding::Start() { std::unique_lock lock(mutex_); int32_t ret; @@ -167,6 +171,7 @@ int32_t Transcoding::Start() { doneCond_.notify_all(); return AVCODEC_SAMPLE_ERR_OK; } +// [Start end_transcoding] void Transcoding::Stop() { StartRelease(); @@ -227,6 +232,7 @@ void Transcoding::Release() { AVCODEC_SAMPLE_LOGI("Release Succeed"); } +// [Start copy_yuv] void Transcoding::CopyStrideYUV420SP(CodecBufferInfo &encBufferInfo, CodecBufferInfo &bufferInfo) { int32_t videoWidth = videoDecContext_->width; int32_t &stride = videoDecContext_->widthStride; @@ -261,7 +267,9 @@ void Transcoding::CopyStrideYUV420SP(CodecBufferInfo &encBufferInfo, CodecBuffer tempBufferAddr = nullptr; delete tempBufferAddr; } +// [End copy_yuv] +// [Start start_decoder_input_thread] void Transcoding::VideoDecInputThread() { while (true) { CHECK_AND_BREAK_LOG(isStarted_, "Decoder input thread out"); @@ -287,7 +295,9 @@ void Transcoding::VideoDecInputThread() { "VideoDecInputThread Catch EOS, thread out"); } } +// [End start_decoder_input_thread] +// [Start start_decoder_output_thread] void Transcoding::VideoDecOutputThread() { sampleInfo_.frameInterval = MICROSECOND / sampleInfo_.frameRate; while (true) { @@ -311,7 +321,7 @@ void Transcoding::VideoDecOutputThread() { bufferInfo.attr.pts); lock.unlock(); - // 将数据写入到编码队列 + // get Buffer from inputBufferInfoQueue CodecBufferInfo encBufferInfo = videoEncContext_->inputBufferInfoQueue.front(); videoEncContext_->inputBufferInfoQueue.pop(); videoEncContext_->inputFrameCount++; @@ -324,7 +334,6 @@ void Transcoding::VideoDecOutputThread() { encBufferInfo.bufferAddr = OH_AVBuffer_GetAddr(reinterpret_cast(encBufferInfo.buffer)); bufferInfo.bufferAddr = OH_AVBuffer_GetAddr(reinterpret_cast(bufferInfo.buffer)); CopyStrideYUV420SP(encBufferInfo, bufferInfo); -// CopyStrideRGBA(encBufferInfo, bufferInfo); AVCODEC_SAMPLE_LOGW( "Out encBufferInfo flags: %{public}u, offset: %{public}d, pts: %{public}u, size: %{public}d" PRId64, @@ -332,11 +341,11 @@ void Transcoding::VideoDecOutputThread() { OH_AVBuffer_SetBufferAttr(reinterpret_cast(encBufferInfo.buffer), &encBufferInfo.attr); - // 释放解码输出队列资源 + // Free Decoder's output buffer int32_t ret = videoDecoder_->FreeOutputBuffer(bufferInfo.bufferIndex, false); CHECK_AND_BREAK_LOG(ret == AVCODEC_SAMPLE_ERR_OK, "Decoder output thread out"); - // 将缓存推送给编码器 + // Push input buffer to Encoder videoEncoder_->PushInputBuffer(encBufferInfo); if (bufferInfo.attr.flags & AVCODEC_BUFFER_FLAGS_EOS) { @@ -345,7 +354,9 @@ void Transcoding::VideoDecOutputThread() { } } } +// [End start_decoder_output_thread] +// [Start start_Encoder_output_thread] void Transcoding::VideoEncOutputThread() { while (true) { std::unique_lock lock(videoEncContext_->outputMutex); @@ -378,4 +389,5 @@ void Transcoding::VideoEncOutputThread() { } AVCODEC_SAMPLE_LOGI("Exit, frame count: %{public}u", videoEncContext_->outputFrameCount); StartRelease(); -} \ No newline at end of file +} +// [End start_Encoder_output_thread] \ No newline at end of file diff --git a/entry/src/main/ets/pages/VideoPlayer.ets b/entry/src/main/ets/pages/VideoPlayer.ets index 33314fa..c9238b1 100644 --- a/entry/src/main/ets/pages/VideoPlayer.ets +++ b/entry/src/main/ets/pages/VideoPlayer.ets @@ -32,10 +32,6 @@ export struct VideoPlayer { private controller: VideoController = new VideoController(); private transController: VideoController = new VideoController(); - // onBackPress() { - // this.pageInfos.popToIndex(-1); - // } - build() { Column() { Row() { @@ -219,7 +215,7 @@ export struct VideoPlayer { Blank() Column() { - Button('返回首页') + Button($r('app.string.return')) .width('100%') .onClick(() => { this.pageInfos.popToIndex(-1); diff --git a/entry/src/main/resources/base/element/string.json b/entry/src/main/resources/base/element/string.json index 05b9339..fbcfb06 100644 --- a/entry/src/main/resources/base/element/string.json +++ b/entry/src/main/resources/base/element/string.json @@ -56,6 +56,10 @@ "name": "after_transcoding", "value": "After" }, + { + "name": "return", + "value": "Return" + }, { "name": "alert_setting", "value": "The setting is not supported by the current device." diff --git a/entry/src/main/resources/en_US/element/string.json b/entry/src/main/resources/en_US/element/string.json index d0ff7a1..556498d 100644 --- a/entry/src/main/resources/en_US/element/string.json +++ b/entry/src/main/resources/en_US/element/string.json @@ -68,6 +68,10 @@ "name": "saveButtonCancel", "value": "Cancel" }, + { + "name": "return", + "value": "Return" + }, { "name": "saveButtonTitle", "value": "Confirm the video storage location" diff --git a/entry/src/main/resources/zh_CN/element/string.json b/entry/src/main/resources/zh_CN/element/string.json index 8f6b093..fe0c9ab 100644 --- a/entry/src/main/resources/zh_CN/element/string.json +++ b/entry/src/main/resources/zh_CN/element/string.json @@ -69,6 +69,10 @@ "name": "saveButtonCancel", "value": "取消" }, + { + "name": "return", + "value": "返回首页" + }, { "name": "saveButtonTitle", "value": "视频保存位置确认" -- Gitee