diff --git a/Cargo.lock b/Cargo.lock index df32fb6..9e1fb41 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -395,7 +395,7 @@ dependencies = [ [[package]] name = "biliup-cli" -version = "1.1.19" +version = "1.1.20" dependencies = [ "async-channel", "async-trait", @@ -3641,7 +3641,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "stream-gears" -version = "1.1.19" +version = "1.1.20" dependencies = [ "async-channel", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index 2f29381..fa5046d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ members = [ resolver = "3" [workspace.package] -version = "1.1.19" +version = "1.1.20" [workspace.dependencies] serde = { version = "1.0", features = ["derive"] } diff --git a/README.md b/README.md index 8fc76a8..49c0821 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ Options: 2. 安装:`uv tool install biliup` 3. 启动:`biliup server --auth` 4. 访问 WebUI:`http://your-ip:19159` - +* 后台运行 `nohup biliup server --auth &` ### Termux - 详见[Wiki](https://github.com/biliup/biliup/wiki/Termux-%E4%B8%AD%E4%BD%BF%E7%94%A8-biliup) diff --git a/app/(app)/job/page.tsx b/app/(app)/job/page.tsx index 7c30eb2..1cef77b 100644 --- a/app/(app)/job/page.tsx +++ b/app/(app)/job/page.tsx @@ -20,6 +20,7 @@ import Filter from "@/app/(app)/job/Filter"; export default function Home() { const { Header, Footer, Sider, Content } = Layout const { data: data, error, isLoading } = useSWR('/v1/streamer-info', fetcher) + if (isLoading) { return } @@ -56,29 +57,7 @@ export default function Home() { render: (time: number) => humDate(time), }, ] - const expandRowRender = (record: any, index: number | undefined) => { - return ( - <> - 文件列表: - {record.files.map( - (it: { - id: Key | null | undefined - file: - | string - | number - | boolean - | ReactElement> - | Iterable - | ReactPortal - | null - | undefined - }) => { - return
  文件名:{it.file}
- } - )} - - ) - } + return ( <>
@@ -123,3 +102,29 @@ export default function Home() { ) } + + +// 创建一个子组件 +const FileLists = ({ recordId }: { recordId: string }) => { + const { data: files, isLoading } = useSWR( + `/v1/streamer-info/files/${recordId}`, + fetcher + ) + + if (isLoading) return
加载中...
+ if (!files || files.length === 0) return
暂无文件
+ + return ( + <> + 文件列表: + {files.map((it: any) => ( +
  文件名:{it.file}
+ ))} + + ) +} + +// 在 expandRowRender 中使用 +const expandRowRender = (record: any) => { + return +} diff --git a/crates/biliup-cli/src/server/api/endpoints.rs b/crates/biliup-cli/src/server/api/endpoints.rs index e9184f7..8afd6c0 100644 --- a/crates/biliup-cli/src/server/api/endpoints.rs +++ b/crates/biliup-cli/src/server/api/endpoints.rs @@ -291,14 +291,24 @@ pub async fn get_streamer_info( .await .change_context(AppError::Unknown) .map_err(report_to_response)?; + + Ok(Json(streamer_infos)) +} + +pub async fn get_streamer_info_files( + // Extension(streamers_service): Extension, + State(pool): State, + Path(id): Path, +) -> Result>, Response> { let file_items = FileItem::select() + .where_("streamer_info_id = ?") + .bind(id) .fetch_all(&pool) .await .change_context(AppError::Unknown) .map_err(report_to_response)?; - println!("{:?}", file_items); - Ok(Json(streamer_infos)) + Ok(Json(file_items)) } pub async fn get_upload_streamers_endpoint( diff --git a/crates/biliup-cli/src/server/common/download.rs b/crates/biliup-cli/src/server/common/download.rs index a05a80f..554978c 100644 --- a/crates/biliup-cli/src/server/common/download.rs +++ b/crates/biliup-cli/src/server/common/download.rs @@ -216,6 +216,8 @@ impl SegmentEventProcessor { move |event| { match event { SegmentEvent::Start { next_file_path } => { + unreachable!("应没有任何位置发出此事件"); + // 开始下载时,获取到的是将要下载的文件名,此时文件还未生成 // 触发弹幕滚动保存 if let Some(ref client) = danmaku && let Err(e) = client @@ -225,6 +227,7 @@ impl SegmentEventProcessor { } } SegmentEvent::Segment(event) => { + // 分段时,获取到的是已下载的文件名 // 触发弹幕滚动保存 if let Some(ref client) = danmaku && let Err(e) = client.rolling( diff --git a/crates/biliup-cli/src/server/core/downloader/ffmpeg_downloader.rs b/crates/biliup-cli/src/server/core/downloader/ffmpeg_downloader.rs index c10f008..21b3091 100644 --- a/crates/biliup-cli/src/server/core/downloader/ffmpeg_downloader.rs +++ b/crates/biliup-cli/src/server/core/downloader/ffmpeg_downloader.rs @@ -233,27 +233,25 @@ impl FfmpegDownloader { bail!(AppError::Custom("Process handle not found".to_string())); } }; + // 退出时,重命名文件 + let part_file = format!("{}.part", output_file.display()); + tokio::fs::rename(&part_file, &output_file) + .await + .change_context(AppError::Unknown)?; // let (tx, rx) = bounded(16); // 分段回调 + // 触发分段回调 + callback(SegmentEvent::Segment( + SegmentInfo { + prev_file_path: output_file, + segment_index: 0, + next_file_path: None, + } + )); // 根据退出码判断状态 match status.code() { Some(0) => { - // 正常退出,重命名文件 - let part_file = format!("{}.part", output_file.display()); - tokio::fs::rename(&part_file, &output_file) - .await - .change_context(AppError::Unknown)?; - - // 触发分段回调 - - // segment_callback(SegmentEvent { - // file_path: output_file, - // segment_index: 0, - // start_time: std::time::SystemTime::now(), - // end_time: std::time::SystemTime::now(), - // }); - Ok(DownloadStatus::SegmentCompleted) } Some(255) => Ok(DownloadStatus::StreamEnded), diff --git a/crates/biliup-cli/src/server/core/plugin.rs b/crates/biliup-cli/src/server/core/plugin.rs index 02a43eb..c0e490c 100644 --- a/crates/biliup-cli/src/server/core/plugin.rs +++ b/crates/biliup-cli/src/server/core/plugin.rs @@ -91,7 +91,7 @@ pub trait DownloadPlugin { raw_stream_url, config, Vec::new(), - DownloaderType::FfmpegInternal, + DownloaderType::FfmpegExternal, )) } // Some(DownloaderType::StreamGears) => { diff --git a/crates/biliup-cli/src/server/core/plugin/yy.rs b/crates/biliup-cli/src/server/core/plugin/yy.rs index 7e3b2fa..9ac458c 100644 --- a/crates/biliup-cli/src/server/core/plugin/yy.rs +++ b/crates/biliup-cli/src/server/core/plugin/yy.rs @@ -108,17 +108,15 @@ impl DownloadPlugin for YY { .to_string(); // 构建URL - let url = format!( - "https://stream-manager.yy.com/v3/channel/streams?uid=0&cid={}&sid={}&appid=0&sequence={}&encode=json", - rid, rid, millis_13 - ); - // 发送POST请求并处理响应 let result = ctx .worker .client .client - .post(&url) + .post(&format!( + "https://stream-manager.yy.com/v3/channel/streams?uid=0&cid={}&sid={}&appid=0&sequence={}&encode=json", + rid, rid, millis_13 + )) .timeout(std::time::Duration::from_secs(30)) .headers(self.fake_headers.clone()) .body(data) @@ -129,7 +127,6 @@ impl DownloadPlugin for YY { .await .change_context(AppError::Custom(format!("解析json出错 rid: {rid}")))?; - println!("{:#?}", result); let Some(stream_url) = result .get("avp_info_res") .and_then(|info| info.get("stream_line_addr")) diff --git a/crates/biliup-cli/src/server/infrastructure/models.rs b/crates/biliup-cli/src/server/infrastructure/models.rs index d88611c..f7720f8 100644 --- a/crates/biliup-cli/src/server/infrastructure/models.rs +++ b/crates/biliup-cli/src/server/infrastructure/models.rs @@ -3,6 +3,7 @@ pub mod hook_step; pub mod live_streamer; pub mod upload_streamer; +use chrono::serde::ts_seconds; use chrono::{DateTime, Utc}; use ormlite::{Insert, Model}; use serde::{Deserialize, Serialize}; @@ -19,6 +20,7 @@ pub struct StreamerInfo { pub url: String, /// 直播标题 pub title: String, + #[serde(with = "ts_seconds")] /// 直播开始时间 pub date: DateTime, /// 直播封面路径(可选) diff --git a/crates/biliup-cli/src/server/router.rs b/crates/biliup-cli/src/server/router.rs index 2081e7e..1434e8c 100644 --- a/crates/biliup-cli/src/server/router.rs +++ b/crates/biliup-cli/src/server/router.rs @@ -1,14 +1,7 @@ use crate::server::api::bilibili_endpoints::{ archive_pre_endpoint, get_myinfo_endpoint, get_proxy_endpoint, }; -use crate::server::api::endpoints::{ - add_upload_streamer_endpoint, add_user_endpoint, delete_streamers_endpoint, - delete_template_endpoint, delete_user_endpoint, get_configuration, get_qrcode, get_status, - get_streamer_info, get_streamers_endpoint, get_upload_streamer_endpoint, - get_upload_streamers_endpoint, get_users_endpoint, get_videos, login_by_qrcode, - pause_streamers_endpoint, post_streamers_endpoint, post_uploads, put_configuration, - put_streamers_endpoint, -}; +use crate::server::api::endpoints::{add_upload_streamer_endpoint, add_user_endpoint, delete_streamers_endpoint, delete_template_endpoint, delete_user_endpoint, get_configuration, get_qrcode, get_status, get_streamer_info, get_streamer_info_files, get_streamers_endpoint, get_upload_streamer_endpoint, get_upload_streamers_endpoint, get_users_endpoint, get_videos, login_by_qrcode, pause_streamers_endpoint, post_streamers_endpoint, post_uploads, put_configuration, put_streamers_endpoint}; use crate::server::infrastructure::service_register::ServiceRegister; use axum::Router; use axum::body::Body; @@ -36,6 +29,7 @@ pub fn router(service_register: ServiceRegister) -> Router<()> { ) // 主播信息路由 .route("/v1/streamer-info", get(get_streamer_info)) // 获取主播信息 + .route("/v1/streamer-info/files/{id}", get(get_streamer_info_files)) // 获取主播信息 // 上传模板管理路由 .route("/v1/upload/streamers", get(get_upload_streamers_endpoint)) // 获取上传模板列表 .route(