Skip to content
Merged
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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -352,4 +352,5 @@ $RECYCLE.BIN/
*.ass
*.xml
*.png
printdens.py
printdens.py
*.mp4
23 changes: 22 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,32 @@ Auto slice the shorts based on the density of danmaku.

- Detect the dense period of danmaku based on the sliding window algorithm.
- Slice the video based on the density of danmaku.
- Support GPU accelerated calculation.
- Support GPU accelerated calculation.(Automatically choose whether to use GPU acceleration)
- Support custom quantity slicing videos.
- Support custom slice duration.

## Prerequisites

To use this tool, you need to install ffmpeg first.

- Windows: `choco install ffmpeg` (via [Chocolatey](https://chocolatey.org/)) or other methods.
- macOS: `brew install ffmpeg` (via [Homebrew](https://brew.sh/)).
- Linux: `sudo apt install ffmpeg` (Debian/Ubuntu).

More OS please refer to the [official website](https://ffmpeg.org/download.html).

## Usage

### cli usage

```bash
python -m autoslice.autosv
```

### api usage

```python
from autoslice.autosv import slice_video_by_danmaku

slice_video_by_danmaku(ass_path, video_path, duration=300, top_n=3, max_overlap=60, step=1)
```
30 changes: 27 additions & 3 deletions autoslice/autosv.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Copyright (c) 2025 auto-slice-video

import os
from .calculate.selection import find_dense_periods
from .slice.slice_video import slice_video

def parse_time(time_str):
"""Convert ASS time format to seconds with milliseconds."""
Expand All @@ -19,6 +21,28 @@ def extract_timestamps(file_path):
timestamps.append(start_time)
return timestamps

timestamps = extract_timestamps('./sample.ass')
dense_periods = find_dense_periods(timestamps, 300, 3, 60)
print(dense_periods)
def slice_video_by_danmaku(ass_path, video_path, duration=300, top_n=3, max_overlap=60, step=1):
"""
Slice the video by the dense periods of danmaku.

Args:
ass_path: The path to the ASS file.
video_path: The path to the video file.
duration: The duration of the slice.
top_n: The number of top dense periods to return.
max_overlap: The maximum allowed overlap between periods (in seconds).
step: The step size for sliding window (in seconds).
"""
output_folder = os.path.dirname(video_path)
video_name = os.path.splitext(os.path.basename(video_path))[0]
timestamps = extract_timestamps(ass_path)
dense_periods = find_dense_periods(timestamps, duration, top_n, max_overlap, step)
print("The dense periods and their count are:")
i = 1
for period in dense_periods:
print(f"Start from {period[0]} seconds with the count is {period[1]}")
slice_video(video_path, f'{output_folder}/{video_name}_{i}.mp4', period[0], duration)
i += 1

if __name__ == "__main__":
slice_video_by_danmaku('./sample.ass', './sample.mp4', 300, 3, 60, 1)
6 changes: 3 additions & 3 deletions autoslice/calculate/selection.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ def check_cuda_available():
except ImportError:
USE_GPU = False

def find_dense_periods(timestamps, window_size=300, top_n=3, max_overlap=60):
def find_dense_periods(timestamps, window_size=300, top_n=3, max_overlap=60, step=1):
"""Find dense periods using either GPU or CPU implementation based on GPU availability."""
if USE_GPU:
print("Using GPU implementation")
return find_dense_periods_gpu(timestamps, window_size, top_n, max_overlap)
return find_dense_periods_gpu(timestamps, window_size, top_n, max_overlap, step)

print("Using CPU implementation")
return find_dense_periods_cpu(timestamps, window_size, top_n, max_overlap)
return find_dense_periods_cpu(timestamps, window_size, top_n, max_overlap, step)

29 changes: 29 additions & 0 deletions autoslice/slice/slice_video.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Copyright (c) 2024 bilive.
# Copyright (c) 2025 auto-slice-video

import subprocess

def format_time(seconds):
"""Format seconds to hh:mm:ss."""
h = int(seconds // 3600)
m = int((seconds % 3600) // 60)
s = int(seconds % 60)
return f"{h:02}:{m:02}:{s:02}"

def slice_video(video_path, output_path, start_time, duration=30):
"""Slice the video using ffmpeg."""
duration = format_time(duration)
command = [
'ffmpeg',
'-ss', format_time(start_time),
'-i', video_path,
'-t', duration,
'-map_metadata', '-1',
'-c:v', 'copy',
'-c:a', 'copy',
output_path
]
try:
result = subprocess.run(command, check=True, capture_output=True, text=True)
except subprocess.CalledProcessError as e:
print(f"Error: {e.stderr}")