Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add FFMpeg recording option. #1

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
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
19 changes: 11 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,18 @@ Installation:
- To install, clone this repo and run `pip install -e .` in the directory containing `setup.py`.
- This should give you access to the `autoleagueplay` command line tool. Try `autoleagueplay --help`.
- Run the `autoleagueplay setup <league_dir>` command to set the directory where you want your league to be stored.
- To use ffmpeg recoding you need to also install [virtual-audio-grabber](https://github.com/rdp/screen-capture-recorder-to-video-windows-free/releases).

Usage:
```
autoleagueplay setup <working_dir> | Setup a league directory. Required for some other commands.
autoleagueplay (odd | even) [--list | --results --test] | Plays (or lists) an odd or even week from the given ladder.
autoleagueplay fetch <week_num> | Fetches the given ladder from the Google Sheets.
autoleagueplay test | Checks if all bots are present in the bot folder.
autoleagueplay leaderboard (odd | even) | Generate a leaderboard image.
autoleagueplay leaderboard (clip | symbols | legend) | Generate a clip or legend for the leaderboard, or update symbols.
autoleagueplay (-h | --help) | Show commands and options.
autoleagueplay --version | Show version.
autoleagueplay setup <working_dir> | Setup a league directory. Required for some other commands.
autoleagueplay (odd | even) [--list | --results --test | --record] | Plays (or lists) an odd or even week from the given ladder.
autoleagueplay fetch <week_num> | Fetches the given ladder from the Google Sheets.
autoleagueplay test | Checks if all bots are present in the bot folder.
autoleagueplay leaderboard (odd | even) | Generate a leaderboard image.
autoleagueplay leaderboard (clip | symbols | legend) | Generate a clip or legend for the leaderboard, or update symbols.
autoleagueplay (-h | --help) | Show commands and options.
autoleagueplay --version | Show version.
```

Options:
Expand All @@ -28,6 +29,7 @@ Options:
--list Instead of playing the matches, the list of matches is printed.
--results Like --list but also shows the result of matches that has been played.
--test Checks if all needed bots are present in the bot folder.
--record Record matches with ffmpeg.
-h --help Show this screen.
--version Show version.
```
Expand All @@ -36,6 +38,7 @@ The working directory contains:
- `ladder.txt`. This contains the bot names separated by newlines (it can be copy-pasted directly from the sheet, or fetched with the fetch command).
- `bots/`. Directory containing the bots and their files.
- `results/`. Directory containing results. Each match will get a json file with all the relevant data, and they are named something like `quantum_reliefbot_vs_atlas_result.json`.
- `results/videos/`. Directory containing video recordings from ffmpeg.

When running the script use either `odd` or `even` as argument to set what type of week it should play:
- Odd: Overclocked, Circuit, Transitor, ect plays.
Expand Down
5 changes: 3 additions & 2 deletions autoleagueplay/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Usage:
autoleagueplay setup <working_dir>
autoleagueplay (odd | even) [--replays=R|--list|--results|--test]
autoleagueplay (odd | even) [--replays=R|--list|--results|--test|--record]
autoleagueplay test
autoleagueplay fetch <week_num>
autoleagueplay leaderboard (odd | even)
Expand All @@ -15,6 +15,7 @@
--list Instead of playing the matches, the list of matches is printed.
--results Like --list but also shows the result of matches that has been played.
--test Checks if all needed bots are in the bot folder.
--record Record matches with ffmpeg.
-h --help Show this screen.
--version Show version.
"""
Expand Down Expand Up @@ -79,7 +80,7 @@ def main():
elif arguments['--test']:
check_bot_folder(working_dir, arguments['odd'])
else:
run_league_play(working_dir, arguments['odd'], replay_preference)
run_league_play(working_dir, arguments['odd'], replay_preference, arguments['--record'])

elif arguments['test']:
check_bot_folder(working_dir)
Expand Down
Binary file added autoleagueplay/bin/ffmpeg.exe
Binary file not shown.
21 changes: 21 additions & 0 deletions autoleagueplay/match_recorder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import subprocess
import signal
import os

from autoleagueplay.paths import WorkingDir, PackageFiles

class Recorder:
def __init__(self, division, participants, working_dir: WorkingDir):
self.output_file = f'[{division}] {participants[0]} vs {participants[1]}.mkv'
self.output_file_path = working_dir.match_recordings / self.output_file

def start(self):
self.process = subprocess.Popen(
f'{str(PackageFiles.ffmpeg_bin)} -f gdigrab -draw_mouse 0 -framerate 60 -i title="Rocket League (32-bit, DX9, Cooked)" -f dshow -i audio="virtual-audio-capturer" -c:v h264_nvenc -b:v 16000k "{self.output_file_path}" -y',
stdout=subprocess.PIPE
)
print(f'ffmpeg recoding started... pid: {self.process.pid}')

def stop(self):
print(f'ffmpeg recoding stopped... killing pid: {self.process.pid}')
os.kill(self.process.pid, signal.SIGTERM)
4 changes: 4 additions & 0 deletions autoleagueplay/paths.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,15 @@ def __init__(self, working_dir: Path):
self.ladder = self._working_dir / 'ladder.txt'
self.new_ladder = self._working_dir / 'ladder_new.txt'
self.match_results = self._working_dir / f'results'
self.match_recordings = self._working_dir / 'results' / 'videos'
self.bots = working_dir / 'bots'
self.overlay_interface = working_dir / 'current_match.json'
self._ensure_directory_structure()

def _ensure_directory_structure(self):
self.ladder.touch(exist_ok=True)
self.match_results.mkdir(exist_ok=True)
self.match_recordings.mkdir(exist_ok=True)
self.bots.mkdir(exist_ok=True)

def get_match_result(self, division_index: int, blue: str, orange: str) -> Path:
Expand Down Expand Up @@ -69,3 +71,5 @@ class PackageFiles:

sheets_token = _package_dir / 'cred' / 'sheets-api-token.pickle'
credentials = _package_dir / 'cred' / 'credentials.json'

ffmpeg_bin = _package_dir / 'bin' / 'ffmpeg.exe'
9 changes: 8 additions & 1 deletion autoleagueplay/run_matches.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from autoleagueplay.overlay import OverlayData
from autoleagueplay.paths import WorkingDir, PackageFiles
from autoleagueplay.replays import ReplayPreference, ReplayMonitor
from autoleagueplay.match_recorder import Recorder

logger = get_logger('autoleagueplay')

Expand Down Expand Up @@ -48,7 +49,7 @@ def make_bot_config(config_bundle: BotConfigBundle, team: Team) -> PlayerConfig:
return player_config


def run_league_play(working_dir: WorkingDir, odd_week: bool, replay_preference: ReplayPreference):
def run_league_play(working_dir: WorkingDir, odd_week: bool, replay_preference: ReplayPreference, ffmpeg_record: bool):
"""
Run a league play event by running round robins for half the divisions. When done, a new ladder file is created.
"""
Expand Down Expand Up @@ -94,6 +95,10 @@ def run_league_play(working_dir: WorkingDir, odd_week: bool, replay_preference:
assert match_participants[0] in bots, f'{match_participants[0]} was not found in \'{working_dir.bots}\''
assert match_participants[1] in bots, f'{match_participants[1]} was not found in \'{working_dir.bots}\''

if ffmpeg_record:
ffmpeg_recorder = Recorder(Ladder.DIVISION_NAMES[div_index], match_participants, working_dir)
ffmpeg_recorder.start()

# Play the match
print(f'Starting match: {match_participants[0]} vs {match_participants[1]}. Waiting for match to finish...')
match_config = make_match_config(working_dir, bots[match_participants[0]], bots[match_participants[1]])
Expand Down Expand Up @@ -130,6 +135,8 @@ def run_league_play(working_dir: WorkingDir, odd_week: bool, replay_preference:
# Let the winner celebrate and the scoreboard show for a few seconds.
# This sleep not required.
time.sleep(8)
if ffmpeg_record:
ffmpeg_recorder.stop()

print(f'{Ladder.DIVISION_NAMES[div_index]} division done')
event_results.append(rr_results)
Expand Down