375 lines
11 KiB
C++
375 lines
11 KiB
C++
#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
|