feat(media): голосовые сообщения и видеокружки

- голосовые: запись/отправка/воспроизведение, Ogg/Opus (libopus FFI на Windows/Android), волна, анимации, lock + slide-to-cancel
- видеокружки: нативная квадратная запись 480x480 (Camera2 + GL), аудио mono 48k, снятие video edit-list для прохождения серверного валидатора
- file_uploader: единый uploadMediaFile (аудио+видео), чтение полного ответа CDN
- проигрывание видео и кружков в message_bubble
This commit is contained in:
klockky
2026-06-25 12:53:11 +03:00
parent c4afc94a7d
commit 37e3763384
20 changed files with 3021 additions and 79 deletions
+8
View File
@@ -127,6 +127,11 @@ class VideoAttachment extends MessageAttachment {
final int? duration;
final int? size;
/// 0 — обычное видео, 1 — видеосообщение-кружок.
final int? videoType;
bool get isNote => videoType == 1;
const VideoAttachment({
super.previewData,
super.baseUrl,
@@ -138,6 +143,7 @@ class VideoAttachment extends MessageAttachment {
this.height,
this.duration,
this.size,
this.videoType,
}) : super(type: AttachmentType.video);
factory VideoAttachment.fromMap(Map<String, dynamic> map) {
@@ -151,6 +157,7 @@ class VideoAttachment extends MessageAttachment {
height: map['height'] as int?,
duration: map['duration'] as int?,
size: map['size'] as int?,
videoType: map['videoType'] as int?,
);
}
@@ -166,6 +173,7 @@ class VideoAttachment extends MessageAttachment {
'height': height,
'duration': duration,
'size': size,
'videoType': videoType,
};
}