maxbot 0.2.2

Автоматизация работы с чат-ботами на платформе MAX (max.ru)
Documentation
//! Методы для работы с видео.

use crate::client::MaxClient;
use crate::error::Result;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

/// Информация о видеофайле.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VideoInfo {
    /// Токен видео-вложения.
    pub token: String,
    /// Адреса для скачивания или воспроизведения видео.
    pub urls: HashMap<String, String>,
    /// Миниатюра видео.
    pub thumbnail: VideoThumbnail,
    /// Ширина видео в пикселях (может быть 0, если ещё обрабатывается).
    pub width: i32,
    /// Высота видео в пикселях (может быть 0, если ещё обрабатывается).
    pub height: i32,
    /// Длительность видео в секундах.
    pub duration: i32,
}

/// Миниатюра видео.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VideoThumbnail {
    /// URL миниатюры.
    pub url: String,
}

impl MaxClient {
    /// Возвращает информацию о видео по его токену.
    ///
    /// # Аргументы
    ///
    /// * `token` - токен видео, полученный при загрузке или из вложения.
    ///
    /// # Пример
    ///
    /// ```no_run
    /// # use maxbot::MaxClient;
    /// # async fn example(client: &MaxClient) -> Result<(), Box<dyn std::error::Error>> {
    /// let info = client.get_video_info("some_video_token").await?;
    /// println!("Видео: {}, размер: {} байт, длительность: {:?} сек",
    ///          info.filename, info.size, info.duration);
    /// # Ok(())
    /// # }
    /// ```
    pub async fn get_video_info(&self, token: &str) -> Result<VideoInfo> {
        // Токен может содержать '/', кодируем его в %2F, остальное не трогаем
        let encoded_token = token.replace('/', "%2F");
        let path = format!("/videos/{}", encoded_token);
        self.request_with_rate_limit(
            reqwest::Method::GET,
            &path,
            &[],
            None,
        )
        .await
    }

    /// Скачивает содержимое видео по токену.
    ///
    /// # Аргументы
    ///
    /// * `token` - токен видео.
    ///
    /// # Возвращаемое значение
    ///
    /// Вектор байтов с содержимым видеофайла.
    pub async fn download_video(&self, token: &str) -> Result<Vec<u8>> {
        let info = self.get_video_info(token).await?;
        // Ищем любой подходящий URL (например, mp4_480 или первый попавшийся)
        let url = info
            .urls
            .values()
            .next()
            .ok_or_else(|| crate::error::Error::InvalidInput("No video URL found".into()))?;
        let resp = self
            .http
            .get(url)
            .header("Authorization", &self.token)
            .send()
            .await?;
        let bytes = resp.bytes().await?;
        Ok(bytes.to_vec())
    }
}