mirror of
https://github.com/Xinrea/bili-shadowreplay.git
synced 2025-11-24 20:15:34 +08:00
fix: file export in web
This commit is contained in:
2
src-tauri/.gitignore
vendored
2
src-tauri/.gitignore
vendored
@@ -1,6 +1,8 @@
|
||||
# Generated by Cargo
|
||||
# will have compiled files and executables
|
||||
/target/
|
||||
cache
|
||||
output
|
||||
tmps
|
||||
clips
|
||||
data
|
||||
|
||||
@@ -54,6 +54,7 @@ url = "2.5.4"
|
||||
custom-protocol = ["tauri/custom-protocol"]
|
||||
cuda = ["whisper-rs/cuda"]
|
||||
headless = []
|
||||
default = ["headless"]
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
whisper-rs = { version = "0.14.2", default-features = false }
|
||||
|
||||
@@ -5,7 +5,7 @@ live_end_notify = true
|
||||
clip_notify = true
|
||||
post_notify = true
|
||||
auto_subtitle = false
|
||||
whisper_model = ""
|
||||
whisper_model = "./whisper_model.bin"
|
||||
whisper_prompt = "这是一段中文 你们好"
|
||||
clip_name_format = "[{room_id}][{live_id}][{title}][{created_at}].mp4"
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ fn default_auto_subtitle() -> bool {
|
||||
}
|
||||
|
||||
fn default_whisper_model() -> String {
|
||||
"".to_string()
|
||||
"whisper_model.bin".to_string()
|
||||
}
|
||||
|
||||
fn default_whisper_prompt() -> String {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use crate::danmu2ass;
|
||||
use crate::database::record::RecordRow;
|
||||
use crate::database::recorder::RecorderRow;
|
||||
use crate::recorder::danmu::DanmuEntry;
|
||||
@@ -7,10 +8,11 @@ use crate::recorder_manager::RecorderList;
|
||||
use crate::state::State;
|
||||
use crate::state_type;
|
||||
|
||||
#[cfg(not(feature = "headless"))]
|
||||
use auri::State as TauriState;
|
||||
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
#[cfg(not(feature = "headless"))]
|
||||
use {crate::danmu2ass, tauri::State as TauriState};
|
||||
|
||||
#[cfg_attr(not(feature = "headless"), tauri::command)]
|
||||
pub async fn get_recorder_list(state: state_type!()) -> Result<RecorderList, ()> {
|
||||
@@ -158,6 +160,7 @@ pub async fn get_danmu_record(
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ExportDanmuOptions {
|
||||
platform: String,
|
||||
room_id: u64,
|
||||
@@ -167,8 +170,7 @@ pub struct ExportDanmuOptions {
|
||||
ass: bool,
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "headless"))]
|
||||
#[tauri::command]
|
||||
#[cfg_attr(not(feature = "headless"), tauri::command)]
|
||||
pub async fn export_danmu(
|
||||
state: state_type!(),
|
||||
options: ExportDanmuOptions,
|
||||
|
||||
@@ -17,10 +17,10 @@ use crate::{
|
||||
},
|
||||
message::{delete_message, get_messages, read_message},
|
||||
recorder::{
|
||||
add_recorder, delete_archive, fetch_hls, force_start, force_stop, get_archive,
|
||||
get_archives, get_danmu_record, get_recent_record, get_recorder_list, get_room_info,
|
||||
get_today_record_count, get_total_length, remove_recorder, send_danmaku,
|
||||
set_auto_start,
|
||||
add_recorder, delete_archive, export_danmu, fetch_hls, force_start, force_stop,
|
||||
get_archive, get_archives, get_danmu_record, get_recent_record, get_recorder_list,
|
||||
get_room_info, get_today_record_count, get_total_length, remove_recorder, send_danmaku,
|
||||
set_auto_start, ExportDanmuOptions,
|
||||
},
|
||||
utils::{get_disk_info, DiskInfo},
|
||||
video::{
|
||||
@@ -43,9 +43,9 @@ use crate::{
|
||||
recorder_manager::{ClipRangeParams, RecorderList},
|
||||
state::State,
|
||||
};
|
||||
use axum::response::sse;
|
||||
use axum::{extract::Query, response::sse};
|
||||
use axum::{
|
||||
extract::{Json, Path, Query},
|
||||
extract::{Json, Path},
|
||||
http::StatusCode,
|
||||
response::{IntoResponse, Sse},
|
||||
routing::{get, post},
|
||||
@@ -834,6 +834,20 @@ async fn handler_fetch(
|
||||
Ok((status, response_headers, body))
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct ExportDanmuRequest {
|
||||
options: ExportDanmuOptions,
|
||||
}
|
||||
|
||||
async fn handler_export_danmu(
|
||||
state: axum::extract::State<State>,
|
||||
Json(params): Json<ExportDanmuRequest>,
|
||||
) -> Result<Json<ApiResponse<String>>, ApiError> {
|
||||
let result = export_danmu(state.0, params.options).await?;
|
||||
Ok(Json(ApiResponse::success(result)))
|
||||
}
|
||||
|
||||
async fn handler_hls(
|
||||
state: axum::extract::State<State>,
|
||||
Path(uri): Path<String>,
|
||||
@@ -1138,6 +1152,7 @@ pub async fn start_api_server(state: State) {
|
||||
"/api/encode_video_subtitle",
|
||||
post(handler_encode_video_subtitle),
|
||||
)
|
||||
.route("/api/export_danmu", post(handler_export_danmu))
|
||||
// Utils commands
|
||||
.route("/api/get_disk_info", post(handler_get_disk_info))
|
||||
.route("/api/fetch", post(handler_fetch))
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
import type { Marker } from "./interface";
|
||||
import { createEventDispatcher } from "svelte";
|
||||
import { Tooltip } from "flowbite-svelte";
|
||||
import { invoke } from "../lib/invoker";
|
||||
import { invoke, TAURI_ENV } from "../lib/invoker";
|
||||
import { save } from "@tauri-apps/plugin-dialog";
|
||||
import type { RecordItem } from "./db";
|
||||
const dispatch = createEventDispatcher();
|
||||
@@ -47,12 +47,19 @@
|
||||
.split(" ")[0]
|
||||
.replaceAll("/", "-")}]${archive.title}.txt`;
|
||||
console.log("export to file", file_name);
|
||||
const path = await save({
|
||||
title: "导出标记列表",
|
||||
defaultPath: file_name,
|
||||
});
|
||||
if (!path) return;
|
||||
await invoke("export_to_file", { fileName: path, content: r });
|
||||
if (TAURI_ENV) {
|
||||
const path = await save({
|
||||
title: "导出标记列表",
|
||||
defaultPath: file_name,
|
||||
});
|
||||
if (!path) return;
|
||||
await invoke("export_to_file", { fileName: path, content: r });
|
||||
} else {
|
||||
const a = document.createElement("a");
|
||||
a.href = "data:text/plain;charset=utf-8," + encodeURIComponent(r);
|
||||
a.download = file_name;
|
||||
a.click();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -814,12 +814,20 @@
|
||||
})) as string;
|
||||
|
||||
let file_name = `danmu_${room_id}_${live_id}.${ass ? "ass" : "txt"}`;
|
||||
const path = await save({
|
||||
title: "导出弹幕",
|
||||
defaultPath: file_name,
|
||||
});
|
||||
if (!path) return;
|
||||
await invoke("export_to_file", { fileName: path, content: assContent });
|
||||
if (TAURI_ENV) {
|
||||
const path = await save({
|
||||
title: "导出弹幕",
|
||||
defaultPath: file_name,
|
||||
});
|
||||
if (!path) return;
|
||||
await invoke("export_to_file", { fileName: path, content: assContent });
|
||||
} else {
|
||||
const a = document.createElement("a");
|
||||
a.href =
|
||||
"data:text/plain;charset=utf-8," + encodeURIComponent(assContent);
|
||||
a.download = file_name;
|
||||
a.click();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user