/* Android уже подготовил MP4 и прочитал метаданные в IO; ядро принимает фиксированный target. */ #include #include #include "../../../lib/mem.h" #include "../../../lib/debug_config.h" #include "../../../lib/u_async.h" #include "../../../src/media_async/attachment_send.h" #include "video_sender.h" #include "instance_lite.h" int video_send(const char* channel_id, const char* src_file_path, const char* db_path, int duration_ms, int width, int height, const uint8_t reply_to[32], uint64_t request_id) { (void)db_path; struct UASYNC* ua = instance_lite_get_uasync(); if (!channel_id || !src_file_path || !uasync_is_running(ua) || duration_ms <= 0 || duration_ms > 86400000 || width <= 0 || width > 16384 || height <= 0 || height > 16384 || strlen(src_file_path) >= 1024) { DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "video send: invalid metadata/target or stopped core"); return -1; } struct attachment_send_req* req = u_calloc(1, sizeof(*req)); struct posted_task* post = u_calloc(1, sizeof(*post)); if (!req || !post) { DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "video send: allocation failed"); u_free(req); u_free(post); return -1; } req->inst = instance_lite_get_instance(); req->is_dm = !strncmp(channel_id, "dm:", 3); if (!req->is_dm) { memcpy(req->reply_to, reply_to, sizeof(req->reply_to)); req->request_id = request_id; } snprintf(req->target, sizeof(req->target), "%s", channel_id + (req->is_dm ? 3 : 0)); snprintf(req->source, sizeof(req->source), "%s", src_file_path); req->info.kind = ATTACHMENT_VIDEO; req->info.duration_ms = (uint32_t)duration_ms; req->info.width = (uint16_t)width; req->info.height = (uint16_t)height; req->temporary_source = 1; /* CameraX и picker создают принадлежащие приложению cache-файлы. */ post->callback = attachment_send_trampoline; post->arg = req; uasync_post_reserved(ua, post); return 0; }