mcu_hi3321_watch/tjd/ui/app/album/TjdUiAppAlbumModel.cpp
2025-05-26 20:15:20 +08:00

375 lines
11 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "TjdUiAppAlbumModel.h"
#include "TjdUiAppAlbumPresenter.h"
#include "cJSON.h"
#include "ohos_types.h"
#include "sys_config.h"
#include "power_display_service.h"
#include "sql_setting.h"
#include <algorithm>
#include <cstring>
#include <dirent.h>
#include <fstream>
#include <unordered_map>
#include <unordered_set>
#include "TjdUiSettingCenter.h"
using namespace OHOS;
#define ENABLE_PRINT_INFO 1
#define ENABLE_DEBUG 0
#if ENABLE_PRINT_INFO
#define static_print_info(...) sys_ui_log_i(__VA_ARGS__) // 一般信息打印宏控制
#define static_print_warn(...) sys_ui_log_w(__VA_ARGS__) // 警告信息打印一般常开
#define static_print_error(...) sys_ui_log_e(__VA_ARGS__) // 错误信息打印一般常开
#if ENABLE_DEBUG
#define static_print_debug(...) sys_ui_log_d(__VA_ARGS__) // 调试信息打印
#else
#define static_print_debug(...)
#endif
#else
#define static_print_info(...)
#define static_print_warn(...)
#define static_print_error(...)
#define static_print_debug(...)
#endif
namespace TJD {
#define JSON_PATH TJD_FS_DIR_WF "/wf_config_0.json"
#define SCREEN_AUTO_OFF_TIME (1000 * 60 * 60)
#define ALBUM_JSON_FILE TJD_FS_DIR_ALBUM"/album.json"
static const int32_t WAIT_SURFACE_DEINIT_SUCCESS_US = 10000;
static const int32_t REQUEST_BUFFER_REPET_COUNT = 10;
static const int32_t WAIT_VIDEO_EXIT_SUCCESS_US = 10000;
static const uint32_t WAIT_VIDEO_EXIT_MAX_RETRY_COUNT = 100;
// 函数用于打开并解析JSON文件
static cJSON *parse_json_file(const std::string &filename)
{
std::ifstream file(filename);
std::string json_string;
if (!file.is_open()) {
static_print_error("Failed to open file: %s", filename.c_str());
return nullptr;
}
std::getline(file, json_string, (char)EOF);
file.close();
cJSON *json = cJSON_Parse(json_string.c_str());
if (json == nullptr) {
const char *error_ptr = cJSON_GetErrorPtr();
if (error_ptr != nullptr) {
static_print_error("Error before: %s", error_ptr);
}
static_print_error("Failed to parse JSON");
}
return json;
}
static bool CreatWfJson()
{
TjdUiSettingCenter::GetInstance().ClearExcFile();
// 文件不存在创建新的JSON对象
cJSON *json = cJSON_CreateObject();
// 设置默认属性
cJSON_AddNumberToObject(json, "wf_type", 2);
cJSON_AddStringToObject(json, "wf_preview", "user/tjd_wf/wf_preview_0.hbm");
cJSON_AddStringToObject(json, "bg_res", "user/tjd_album/sea_wave.mp4");
cJSON_AddStringToObject(json, "video_preview", "user/tjd_album/sea_wave.bin");
// 创建txt_position数组并添加元素
cJSON *txt_position = cJSON_CreateArray();
cJSON_AddItemToArray(txt_position, cJSON_CreateNumber(0)); // x坐标
cJSON_AddItemToArray(txt_position, cJSON_CreateNumber(0)); // y坐标
cJSON_AddItemToObject(json, "txt_position", txt_position);
cJSON_AddNumberToObject(json, "txt_align", 0);
cJSON_AddNumberToObject(json, "txt_color", 0);
// 写入文件
char *rendered = cJSON_Print(json);
std::ofstream outfile(JSON_PATH);
if (outfile.is_open()) {
outfile << rendered;
outfile.close();
} else {
// 假设您有一个错误处理函数
static_print_error("Failed to open file for writing: %s", JSON_PATH);
return false;
}
free(rendered);
cJSON_Delete(json);
return true;
}
static std::string extractTimestampFromFilename(const std::string& absFilename)
{
// static_print_debug("extractTimestampFromFilename %s", absFilename.c_str());
auto separatorPos = absFilename.rfind('/');
std::string filename = absFilename.substr(separatorPos + 1);
auto dotPos = filename.rfind('.');
if (dotPos == std::string::npos || dotPos == 0) {
return "0";
}
std::string baseName = filename.substr(0, dotPos);
static_print_debug("baseName %s", baseName.c_str());
std::string timestampStr;
auto it = baseName.begin();
while (it != baseName.end()) {
if (std::isdigit(*it)) {
timestampStr.push_back(*it);
}
++it;
}
// static_print_debug("timestampStr %s", timestampStr.c_str());
if (timestampStr == "") {
return "0";
}
return timestampStr;
}
static uint64_t extractTimestamp(const std::string& path)
{
std::string timestampStr;
timestampStr = extractTimestampFromFilename(path);
return std::stoll(timestampStr);
}
// 插入函数,按照时间戳倒序插入
static void insertAlbumItem(std::list<AlbumItem>& list, const AlbumItem& newItem)
{
// static_print_debug("insertAlbumItem newItem.path:%s", newItem.path);
uint64_t newTimestamp = extractTimestamp(newItem.path);
auto it = list.begin();
bool inserted = false;
while (it != list.end()) {
uint64_t existingTimestamp = extractTimestamp(it->path);
if (newTimestamp > existingTimestamp) {
list.insert(it, newItem);
inserted = true;
break;
}
++it;
}
if (!inserted) {
list.push_back(newItem);
}
// for (auto ii = list.begin(); ii != list.end(); ++ii) {
// static_print_debug("ii:%s", (*ii).path);
// }
}
TjdUiAppAlbumModel &TjdUiAppAlbumModel::GetInstance(void)
{
static TjdUiAppAlbumModel instance;
return instance;
}
int TjdUiAppAlbumModel::GetAllFiles(std::list<AlbumItem> *albumsCaseList)
{
static_print_debug("TjdUiAppAlbumModel::%s", __func__);
int ret;
int i{0};
struct dirent *direntp;
std::list<AlbumItem> videoList;
std::unordered_map<std::string, Album_type> fileNameToTypeMap;
// 打开目录
DIR *dirp = opendir(TJD_FS_DIR_ALBUM);
// 遍历文件
if (dirp != nullptr) {
std::string albumDirPath(TJD_FS_DIR_ALBUM);
while ((direntp = readdir(dirp)) != nullptr) {
std::string filename(direntp->d_name);
if (filename.size() < 4)
continue;
if ((filename.substr(filename.size() - 4) != ".mp4" && filename.substr(filename.size() - 4) != ".bin"))
continue;
Album_type type = (filename.size() >= 4 && filename.substr(filename.size() - 4) == ".mp4")
? Album_type::ALBUM_VIDEO
: Album_type::ALBUM_PHOTO;
std::string fullPath = albumDirPath + "/" + filename;
fileNameToTypeMap[fullPath] = type;
static_print_debug("type:%d filename:%s", (int)type, fullPath.c_str());
}
} else {
static_print_error("TjdUiAppAlbumModel::%s opendir err!", __func__);
return OHOS_FAILURE;
}
// 关闭目录
closedir(dirp);
for (const auto &pair : fileNameToTypeMap) {
Album_type type = pair.second;
std::string filename = pair.first;
if (type == Album_type::ALBUM_VIDEO) {
videoList.emplace_front(i, type, filename.c_str());
} else {
AlbumItem tempItem = {i, type, filename.c_str()};
insertAlbumItem(*albumsCaseList, tempItem);
}
i++;
}
for (auto &photo : *albumsCaseList) {
for (const auto &video : videoList) {
if (photo.hasSameBaseName(video)) {
photo.type = Album_type::ALBUM_VIDEO;
break;
}
}
}
// for (auto &photo : *albumsCaseList) {
// static_print_debug("photo type:%s name:%s",
// photo.type == Album_type::ALBUM_VIDEO ? "ALBUM_VIDEO" : "ALBUM_PHOTO", photo.path);
// }
static_print_debug("TjdUiAppAlbumModel::%s end!", __func__);
return OHOS_SUCCESS;
}
// 删除指定文件
bool TjdUiAppAlbumModel::DeleteFile(Album_type type, const char *filePath)
{
if (type == ALBUM_VIDEO) {
std::string mp4FilePath = filePath;
mp4FilePath = mp4FilePath.substr(0, mp4FilePath.rfind('.') + 1) + "mp4";
if (std::remove(mp4FilePath.c_str()) != 0) {
static_print_error("TjdUiAppAlbumModel::DeleteFile delete %s fail", mp4FilePath.c_str());
return false;
}
}
if (std::remove(filePath) != 0) {
static_print_error("TjdUiAppAlbumModel::DeleteFile delete %s fail", filePath);
return false;
}
return true;
}
void TjdUiAppAlbumModel::UpdateWfJson(Album_type type, const std::string &filename)
{
std::ifstream file(JSON_PATH);
if (!file.good()) {
if (!CreatWfJson()) {
return;
}
} else { // 若文件存在,先删除再创建
if (remove(JSON_PATH) != 0) {
return;
}
if (!CreatWfJson()) {
return;
}
}
cJSON *json = parse_json_file(JSON_PATH);
if (json == nullptr) {
return;
}
if (filename.empty()) {
cJSON_Delete(json);
return;
}
if (type == Album_type::ALBUM_PHOTO) {
cJSON_SetNumberValue(cJSON_GetObjectItem(json, "wf_type"), 0);
cJSON_SetValuestring(cJSON_GetObjectItem(json, "bg_res"), filename.c_str());
cJSON_SetValuestring(cJSON_GetObjectItem(json, "video_preview"), "");
cJSON_SetValuestring(cJSON_GetObjectItem(json, "wf_preview"), filename.c_str());
} else if (type == Album_type::ALBUM_VIDEO) {
cJSON_SetNumberValue(cJSON_GetObjectItem(json, "wf_type"), 2);
std::string mp4_filename = filename.substr(0, filename.rfind('.') + 1) + "mp4";
cJSON_SetValuestring(cJSON_GetObjectItem(json, "bg_res"), mp4_filename.c_str());
cJSON_SetValuestring(cJSON_GetObjectItem(json, "video_preview"), filename.c_str());
cJSON_SetValuestring(cJSON_GetObjectItem(json, "wf_preview"), filename.c_str());
}
char *rendered = cJSON_Print(json);
// 将字符串写回到文件
std::ofstream outfile(JSON_PATH);
if (outfile.is_open()) {
outfile << rendered;
outfile.close();
} else {
static_print_error("Failed to open file for writing: %s", JSON_PATH);
}
sql_setting_set_watch_face_id(0);
free(rendered);
cJSON_Delete(json);
}
AlbumVideoPlayer::AlbumVideoPlayer(Surface *surface, UIButton **buttonArray, std::string uri, bool isPureVideo)
: MediaVideoPlay(surface, nullptr, uri, isPureVideo)
{
for (int i = 0; i < ALBUM_BUTTON_NUM; i++) {
buttonArray_[i] = buttonArray[i];
}
}
AlbumVideoPlayer::~AlbumVideoPlayer()
{
for (int i = 0; i < ALBUM_BUTTON_NUM; i++) {
buttonArray_[i] = nullptr;
}
}
int64_t AlbumVideoPlayer::GetDurationTime(void)
{
int64_t durTime = 0;
MediaMutexLock(mutex_);
if (player_ == NULL) {
static_print_error("AlbumVideoPlayer::%s: can not get duration time!", __func__);
MediaMutexUnLock(mutex_);
return 0;
}
int32_t ret = player_->GetDuration(durTime);
if (ret != 0) {
static_print_error("AlbumVideoPlayer::%s: get duration time failed", __func__);
MediaMutexUnLock(mutex_);
return 0;
}
MediaMutexUnLock(mutex_);
return durTime;
}
void AlbumVideoPlayer::SetUri(std::string uri)
{
MediaMutexLock(mutex_);
if (!isEntered_) {
uri_ = uri;
printf("uri_ set succ\n");
}
MediaMutexUnLock(mutex_);
}
} // namespace TJD