Files
video_probe/init_video_probe_rust.sh
accusys f3e2d2dca7 Initial implementation of video_probe (Rust)
Core modules:
- probe.rs: ffprobe execution logic
- parser.rs: JSON parsing logic
- output.rs: Output formatting
- lib.rs: Library interface
- main.rs: CLI entry point

Features:
- Extract video metadata using ffprobe
- Parse video/audio/subtitle streams
- Save to JSON file
- Console summary output

Documentation:
- Added QUICKSTART.md
- Added ENVIRONMENT_SETUP_REPORT.md
2026-03-07 10:10:19 +08:00

320 lines
7.0 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# 快速启动脚本 - 创建 video_probe Rust 项目
set -e
# 设置 PATHmacOS with Homebrew
export PATH="/opt/homebrew/bin:$PATH"
echo "======================================"
echo "Video Probe (Rust) - 项目初始化"
echo "======================================"
echo ""
# 检查 Rust 是否已安装
if ! command -v rustc &> /dev/null; then
echo "❌ Rust 未安装"
echo ""
echo "请先安装 Rust:"
echo " curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh"
exit 1
fi
echo "✓ Rust 已安装: $(rustc --version)"
echo "✓ Cargo 已安装: $(cargo --version)"
echo ""
# 检查 ffprobe
if ! command -v ffprobe &> /dev/null; then
echo "⚠️ 警告: ffprobe 未找到"
echo " macOS: brew install ffmpeg"
echo " Linux: sudo apt-get install ffmpeg"
echo " Windows: 从 https://ffmpeg.org 下载"
echo ""
fi
# 创建项目
PROJECT_NAME="video_probe"
echo "1. 创建 Cargo 项目..."
if [ -d "$PROJECT_NAME" ]; then
echo " 目录已存在: $PROJECT_NAME"
read -p " 删除并重新创建? (y/N): " confirm
if [ "$confirm" = "y" ] || [ "$confirm" = "Y" ]; then
rm -rf "$PROJECT_NAME"
else
echo " 取消操作"
exit 1
fi
fi
cargo new "$PROJECT_NAME"
cd "$PROJECT_NAME"
echo " ✓ 项目创建成功: $PROJECT_NAME/"
echo ""
# 创建目录结构
echo "2. 创建目录结构..."
mkdir -p src tests docs tests/fixtures
touch src/{lib.rs,probe.rs,parser.rs,metadata.rs,output.rs,error.rs}
touch tests/integration_test.rs
touch docs/{USAGE.md,DEVELOPMENT.md}
echo " ✓ 目录结构创建完成"
echo ""
# 更新 Cargo.toml
echo "3. 配置 Cargo.toml..."
cat > Cargo.toml << 'EOF'
[package]
name = "video_probe"
version = "0.1.0"
edition = "2021"
authors = ["Your Name <your.email@example.com>"]
description = "Extract video metadata using ffprobe"
license = "MIT"
repository = "https://gitea.example.com/yourname/video_probe"
keywords = ["video", "metadata", "ffprobe", "ffmpeg"]
categories = ["command-line-utilities", "multimedia"]
[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
chrono = { version = "0.4", features = ["serde"] }
anyhow = "1.0"
thiserror = "1.0"
clap = { version = "4.0", features = ["derive"] }
[dev-dependencies]
tempfile = "3.8"
[[bin]]
name = "video_probe"
path = "src/main.rs"
EOF
echo " ✓ Cargo.toml 已配置"
echo ""
# 创建 .gitignore
echo "4. 创建 .gitignore..."
cat > .gitignore << 'EOF'
/target/
**/*.rs.bk
*.pdb
Cargo.lock
*.probe.json
*.mp4
*.avi
*.mov
*.mkv
.DS_Store
.vscode/
.idea/
EOF
echo " ✓ .gitignore 已创建"
echo ""
# 创建基础代码模板
echo "5. 创建基础代码模板..."
# src/metadata.rs
cat > src/metadata.rs << 'EOF'
use serde::{Deserialize, Serialize};
use chrono::{DateTime, Utc};
#[derive(Debug, Serialize, Deserialize)]
pub struct VideoMetadata {
pub video_path: String,
pub probed_at: DateTime<Utc>,
pub format: FormatInfo,
pub video_stream: Option<VideoStream>,
pub audio_streams: Vec<AudioStream>,
pub subtitle_streams: Vec<SubtitleStream>,
pub other_streams: Vec<OtherStream>,
}
#[derive(Debug, Serialize, Deserialize, Default)]
pub struct FormatInfo {
pub filename: Option<String>,
pub format_name: Option<String>,
pub format_long_name: Option<String>,
pub duration: f64,
pub size: u64,
pub bit_rate: u64,
pub probe_score: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tags: Option<serde_json::Value>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct VideoStream {
pub index: i32,
pub codec_name: Option<String>,
pub codec_long_name: Option<String>,
pub profile: Option<String>,
pub width: i32,
pub height: i32,
pub pix_fmt: Option<String>,
pub r_frame_rate: Option<String>,
pub avg_frame_rate: Option<String>,
pub bit_rate: Option<u64>,
pub duration: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tags: Option<serde_json::Value>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct AudioStream {
pub index: i32,
pub codec_name: Option<String>,
pub channels: i32,
pub sample_rate: Option<String>,
pub bit_rate: Option<u64>,
pub duration: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tags: Option<serde_json::Value>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct SubtitleStream {
pub index: i32,
pub codec_name: Option<String>,
pub language: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tags: Option<serde_json::Value>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct OtherStream {
pub index: i32,
pub codec_type: String,
pub codec_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tags: Option<serde_json::Value>,
}
EOF
# src/error.rs
cat > src/error.rs << 'EOF'
use thiserror::Error;
#[derive(Debug, Error)]
pub enum ProbeError {
#[error("Video file not found: {0}")]
FileNotFound(String),
#[error("Failed to execute ffprobe: {0}")]
FfprobeExecution(#[from] std::io::Error),
#[error("Failed to parse ffprobe output: {0}")]
ParseError(#[from] serde_json::Error),
#[error("ffprobe returned non-zero exit code: {0}")]
FfprobeFailed(String),
#[error("No video stream found")]
NoVideoStream,
}
pub type Result<T> = std::result::Result<T, ProbeError>;
EOF
echo " ✓ 基础代码模板已创建"
echo ""
# 创建 README
echo "6. 创建 README.md..."
cat > README.md << 'EOF'
# video_probe (Rust)
Extract video metadata using ffprobe
## Installation
### From Source
```bash
git clone https://gitea.example.com/yourname/video_probe.git
cd video_probe
cargo install --path .
```
## Usage
```bash
video_probe video.mp4
```
Output: `video.probe.json`
## Features
- ✅ Fast and efficient (written in Rust)
- ✅ Cross-platform (Linux, macOS, Windows)
- ✅ Comprehensive metadata extraction
- ✅ JSON output format
- ✅ User-friendly console output
## Development
```bash
# Build
cargo build
# Run
cargo run -- video.mp4
# Test
cargo test
# Format code
cargo fmt
# Lint
cargo clippy
```
## Requirements
- Rust 1.70+
- ffprobe (from FFmpeg)
## License
MIT
EOF
echo " ✓ README.md 已创建"
echo ""
# 初始化 Git
echo "7. 初始化 Git 仓库..."
git init
git add .
git commit -m "Initial commit: video_probe Rust project"
echo " ✓ Git 仓库已初始化"
echo ""
# 构建项目
echo "8. 构建项目..."
cargo build
echo " ✓ 项目构建成功"
echo ""
# 完成
echo "======================================"
echo "✅ 项目初始化完成!"
echo "======================================"
echo ""
echo "项目位置: $(pwd)"
echo ""
echo "下一步:"
echo " 1. cd $PROJECT_NAME"
echo " 2. 实现核心功能(参考: VIDEO_PROBE_RUST_DEVELOPMENT.md"
echo " 3. cargo run -- <video_path>"
echo " 4. cargo test"
echo ""
echo "创建 Gitea 仓库:"
echo " 1. 在 Gitea 创建新仓库: video_probe"
echo " 2. git remote add origin <your-gitea-url>"
echo " 3. git push -u origin main"
echo ""