Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .vscode/notes_astro3.code-snippets
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,17 @@
"</details>"
],
"description": "details show code"
},
"details Template show anwser": {
"scope": "markdown",
"prefix": "details_show_anwser",
"body": [
"<details>",
"<summary>${1:如何理解}</summary>",
"$2",
"</details>"
],
"description": "details not open tag in mdx"
},
"blockquote Template": {
"scope": "markdown",
Expand Down
3 changes: 2 additions & 1 deletion astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ export default defineConfig({
external: [
"wavesurfer.js",
"wavesurfer.js/dist/plugins/spectrogram.esm.js",
],
],
sourceMap: "inline",
},
},
},
Expand Down
2 changes: 1 addition & 1 deletion package-changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,4 +131,4 @@ Checking /Users/ninghuiyue/Desktop/ajn404.github.io/package.json

### 问题

问题太多回退了
问题太多,回退了
2 changes: 1 addition & 1 deletion plugin/remark-reading-time.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export function remarkReadingTime() {
return function (tree, { data }) {
const textOnPage = toString(tree);
const readingTime = getReadingTime(textOnPage);
// readingTime.text 会以友好的字符串形式给出阅读时间例如 3 分钟
// readingTime.text 会以友好的字符串形式给出阅读时间,例如 3 分钟.
data.astro.frontmatter.minutesRead = readingTime.text;
data.astro.frontmatter.wordsRead = readingTime.words;

Expand Down
Binary file added public/assets/webp/1.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 13 additions & 12 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pnpm run dev

- <a href="https://ajn404.github.io/" target="_blank">github pages</a>
- <a href="https://ajn404-github-io.pages.dev" target="_blank">cloud flare</a>
- <a href="ajn404-github-io.vercel.app" target="_blank">vercel</a>
- <a href="https://ajn404.gitee.io/" target="_blank">~~gitee pages~~</a>

## snippets
Expand Down Expand Up @@ -118,26 +119,26 @@ pnpm run dev

下面是对每个脚本的解释:

1. **"dev": "astro dev"**:这个命令用于启动 Astro 开发服务器通常用于本地开发和调试
1. **"dev": "astro dev"**:这个命令用于启动 Astro 开发服务器,通常用于本地开发和调试.

2. **"start": "astro dev"**:这个命令与 `dev` 命令相同都是启动 Astro 开发服务器通常 `start` 命令用于生产环境的启动但在这里它被设置为开发模式
2. **"start": "astro dev"**:这个命令与 `dev` 命令相同,都是启动 Astro 开发服务器.通常 `start` 命令用于生产环境的启动,但在这里它被设置为开发模式.

3. **"build": "cross-env NODE_OPTIONS=--max-old-space-size=8192 astro build"**:这个命令用于构建 Astro 项目`cross-env` 是一个工具用于跨平台设置环境变量在这里它将 Node.js 的最大老生代内存限制设置为 8192MB(即 8GB)以防止在构建过程中出现内存不足的错误
3. **"build": "cross-env NODE_OPTIONS=--max-old-space-size=8192 astro build"**:这个命令用于构建 Astro 项目.`cross-env` 是一个工具,用于跨平台设置环境变量.在这里,它将 Node.js 的最大老生代内存限制设置为 8192MB(即 8GB),以防止在构建过程中出现内存不足的错误.

4. **"preview": "astro preview"**:这个命令用于预览构建后的 Astro 项目通常用于检查生产环境中的效果
4. **"preview": "astro preview"**:这个命令用于预览构建后的 Astro 项目,通常用于检查生产环境中的效果.

5. **"astro": "astro"**:这个命令直接调用 Astro CLI允许用户在命令行中使用 Astro 的其他功能
5. **"astro": "astro"**:这个命令直接调用 Astro CLI,允许用户在命令行中使用 Astro 的其他功能.

6. **"hide:toolbar": "astro preferences disable devToolbar"**:这个命令用于禁用 Astro 开发工具栏可能用于在开发时减少界面干扰
6. **"hide:toolbar": "astro preferences disable devToolbar"**:这个命令用于禁用 Astro 开发工具栏,可能用于在开发时减少界面干扰.

7. **"cz": "git add .&&cz&&git push"**:这个命令用于将所有更改添加到 Git 暂存区然后调用 `cz`(通常是指 Commitizen用于生成规范化的提交信息)最后将更改推送到远程仓库
7. **"cz": "git add .&&cz&&git push"**:这个命令用于将所有更改添加到 Git 暂存区,然后调用 `cz`(通常是指 Commitizen,用于生成规范化的提交信息),最后将更改推送到远程仓库.

8. **"prepare": "husky install"**:这个命令用于安装 Husky这是一个 Git hooks 工具通常用于在提交之前运行一些检查或脚本
8. **"prepare": "husky install"**:这个命令用于安装 Husky,这是一个 Git hooks 工具,通常用于在提交之前运行一些检查或脚本.

9. **"format:check": "prettier --plugin-search-dir=. --check ."**:这个命令用于检查代码格式是否符合 Prettier 的标准而不进行实际的格式化
9. **"format:check": "prettier --plugin-search-dir=. --check ."**:这个命令用于检查代码格式是否符合 Prettier 的标准,而不进行实际的格式化.

10. **"format": "prettier --plugin-search-dir=. --write ."**:这个命令用于格式化代码使其符合 Prettier 的标准并直接修改文件
10. **"format": "prettier --plugin-search-dir=. --write ."**:这个命令用于格式化代码,使其符合 Prettier 的标准,并直接修改文件.

11. **"tauri:dev": "tauri dev"**:这个命令用于启动 Tauri 开发服务器通常用于开发桌面应用
11. **"tauri:dev": "tauri dev"**:这个命令用于启动 Tauri 开发服务器,通常用于开发桌面应用.

12. **"tauri:build": "tauri build"**:这个命令用于构建 Tauri 应用生成可供发布的桌面应用程序
12. **"tauri:build": "tauri build"**:这个命令用于构建 Tauri 应用,生成可供发布的桌面应用程序.
77 changes: 77 additions & 0 deletions src/assets/rtsp/demo.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta charset="UTF-8" />
<title>FLV直播测试</title>
<script src="http://cdn.shinobi.video/js/flv.min.js"></script>
<style>
#controls {
margin-top: 10px;
}
button {
padding: 10px;
margin-right: 5px;
width: 200px;
font-size: 20px;
}
</style>
</head>
<body>
<video id="videoElement" controls></video>
<div id="controls">
<button id="playButton">播放</button>
<button id="pauseButton">暂停</button>
<button id="stopButton">停止</button>
<button id="rewindButton">快退 10 秒</button>
</div>
<script>
const videoElement = document.getElementById("videoElement");
const playButton = document.getElementById("playButton");
const pauseButton = document.getElementById("pauseButton");
const stopButton = document.getElementById("stopButton");
const rewindButton = document.getElementById("rewindButton");

let flvPlayer;

if (flvjs.isSupported()) {
flvPlayer = flvjs.createPlayer({
type: "flv",
isLive: true,
url: "/flv/1/s.flv",
});
flvPlayer.attachMediaElement(videoElement);
flvPlayer.on("error", (err) => console.log(err));
flvPlayer.load();

// 播放按钮事件
playButton.addEventListener("click", () => flvPlayer.play());

// 暂停按钮事件
pauseButton.addEventListener("click", () => flvPlayer.pause());

// 停止按钮事件
stopButton.addEventListener("click", () => {
flvPlayer.pause();
flvPlayer.unload(); // 卸载播放器
videoElement.src = ""; // 清空视频源
});

// 快退按钮事件
rewindButton.addEventListener("click", () => rewindCustom(10));

// 快退自定义时间
const rewindCustom = (seconds) => {
videoElement.currentTime = Math.max(0, videoElement.currentTime - seconds);
};

// 快退1秒的键盘事件
document.addEventListener("keydown", (event) => {
if (event.key === "ArrowLeft") {
rewindCustom(1); // 快退1秒
}
});
}
</script>
</body>
</html>
94 changes: 94 additions & 0 deletions src/assets/rtsp/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
const { spawn } = require("child_process");
const { EventEmitter } = require("events");
const express = require("express");
const path = require("path");

const app = express();
const server = require("http").Server(app);
const PORT = 5500;
const RTSP_URL = "rtsp测试地址(替换)";

const emitters = {};
const firstChunks = {};

const initEmitter = feed => {
if (!emitters[feed]) {
emitters[feed] = new EventEmitter().setMaxListeners(0);
}
return emitters[feed];
};

const initFirstChunk = (feed, firstBuffer) => {
if (!firstChunks[feed]) {
firstChunks[feed] = firstBuffer;
}
return firstChunks[feed];
};

console.log(`Starting Express Web Server on Port ${PORT}`);
server.listen(PORT);

// Serve static files
app.use("/libs", express.static(path.join(__dirname, "../../web/libs")));
app.use("/", express.static(__dirname));

// Homepage with video element
app.get("/", (req, res) => {
res.sendFile(path.join(__dirname, "index.html"));
});

// FLV over HTTP
app.get(["/flv", "/flv/:feed/s.flv"], (req, res) => {
const feed = req.params.feed || "1";
req.Emitter = initEmitter(feed);

res.setHeader("Content-Type", "video/x-flv");
res.setHeader("Access-Control-Allow-Origin", "*");

res.write(initFirstChunk(feed, Buffer.alloc(0))); // Initialize with empty buffer

const contentWriter = buffer => res.write(buffer);
req.Emitter.on("data", contentWriter);

res.on("close", () => {
req.Emitter.removeListener("data", contentWriter);
});
});

// Start FFmpeg
console.log("Starting FFMPEG");
let ffmpegArgs = [
"-i",
RTSP_URL,
"-c:v",
"libx264",
"-preset",
"fast",
"-crf",
"23",
"-an",
"-f",
"flv",
"pipe:1",
];

if (RTSP_URL.includes("rtsp://")) {
ffmpegArgs.unshift("-rtsp_transport", "tcp");
}

console.log(`Executing: ffmpeg ${ffmpegArgs.join(" ")}`);
const ffmpeg = spawn("ffmpeg", ffmpegArgs, { stdio: ["pipe", "pipe", "pipe"] });

ffmpeg.on("close", () => {
console.log("FFmpeg process exited");
});

ffmpeg.stderr.on("data", data => {
console.error(`FFmpeg error: ${data.toString()}`);
});

// Data from FFmpeg output
ffmpeg.stdout.on("data", buffer => {
initFirstChunk("1", buffer);
initEmitter("1").emit("data", buffer);
});
2 changes: 1 addition & 1 deletion src/components/astro/canvas/draw.astro
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

function stopDrawing() {
drawing = false;
ctx.beginPath(); // 开始一个新的路径以防止连接上一个绘图
ctx.beginPath(); // 开始一个新的路径,以防止连接上一个绘图
}

function draw(event) {
Expand Down
12 changes: 6 additions & 6 deletions src/components/astro/dom/textarea.astro
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,22 @@
---

<textarea id="textarea" class="min-w-full min-h-[30em] px-5">
姐姐今夜我在德令哈夜色笼罩
姐姐今夜我只有戈壁
姐姐,今夜我在德令哈,夜色笼罩
姐姐,今夜我只有戈壁
草原尽头我两手空空
悲痛时握不住一颗泪滴
姐姐今夜我在德令哈
姐姐,今夜我在德令哈
这是雨水中一座荒凉的城
除了那些路过的和居住的
德令哈……今夜
这是唯一的最后的,抒情。
这是唯一的最后的,草原。
这是唯一的,最后的,抒情.
这是唯一的,最后的,草原.
我把石头还给石头
让胜利的胜利
今夜青稞只属于她自己
一切都在生长
今夜我只有美丽的戈壁 空空
姐姐今夜我不关心人类我只想你
姐姐,今夜我不关心人类,我只想你
</textarea>
<p>
<button id="select-button" class="border-solid border-2 border-indigo-600 p-1 rounded-lg hover:skew-y-2 ">选中第三行</button>
Expand Down
2 changes: 1 addition & 1 deletion src/components/react/d3/textAnimation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const SvgText: React.FC<SvgTextProps> = ({
useEffect(() => {
if (textRef.current) {
const bbox = textRef.current.getBBox(); // 获取文本的边界框
setWidth(bbox.width + 20); // 设置宽度增加一些边距
setWidth(bbox.width + 20); // 设置宽度,增加一些边距
}
}, [text]);

Expand Down
2 changes: 1 addition & 1 deletion src/components/react/features/mouse.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class Mouse extends Component<MouseProps, MouseState> {
}

handleMouseMove(event: React.MouseEvent<HTMLDivElement>) {
// JavaScript 的鼠标事件处理中clientX 和 clientY 属性用于获取鼠标指针相对于浏览器视口(viewport)的坐标
// JavaScript 的鼠标事件处理中,clientX 和 clientY 属性用于获取鼠标指针相对于浏览器视口(viewport)的坐标
this.setState({
x: event.clientX,
y: event.clientY,
Expand Down
10 changes: 5 additions & 5 deletions src/components/react/fiber/2DGraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ import { shaderMaterial } from "@react-three/drei";
const basicVertex = `
void main() {
vec4 modelPosition = modelMatrix * vec4(position, 1.0);
//将模型坐标乘以模型矩阵得到顶点的世界坐标
//将模型坐标乘以模型矩阵,得到顶点的世界坐标
vec4 viewPosition = viewMatrix * modelPosition;
//将世界坐标乘以视图矩阵得到顶点在相机坐标系中的坐标
//将世界坐标乘以视图矩阵,得到顶点在相机坐标系中的坐标
vec4 projectionPosition = projectionMatrix * viewPosition;
//将相机坐标乘以投影矩阵得到顶点在裁剪坐标系中的坐标
//将相机坐标乘以投影矩阵,得到顶点在裁剪坐标系中的坐标.
gl_Position = projectionPosition;
//将裁剪坐标赋值给内置变量 gl_Position它表示最终的顶点位置用于后续的光栅化和片元处理阶段
//将裁剪坐标赋值给内置变量 gl_Position,它表示最终的顶点位置,用于后续的光栅化和片元处理阶段.
}
//这段代码的目的是将顶点从模型坐标系经过模型、视图和投影变换最终将其转换为裁剪坐标
//这段代码的目的是将顶点从模型坐标系经过模型、视图和投影变换,最终将其转换为裁剪坐标.
`;

const circleFragment = `
Expand Down
2 changes: 1 addition & 1 deletion src/components/react/little/CesiumComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const CesiumComponent: React.FC = () => {
// 确保场景已加载完成
viewer.scene.globe.tileLoadProgressEvent.addEventListener(function (event) {
if (event.tilesLoaded === event.tilesToRender) {
// 场景已加载完成可以切换到 2D 模式
// 场景已加载完成,可以切换到 2D 模式
// viewer.scene.mode = SceneMode.SCENE2D;
// console.log(viewer.animation?.container);
}
Expand Down
Loading