Skip to content

Commit e809c5f

Browse files
committed
MVP
1 parent 2d1b3f5 commit e809c5f

17 files changed

+2332
-390
lines changed

.gitmodules

-13
This file was deleted.

CMakeLists.txt

+83-47
Original file line numberDiff line numberDiff line change
@@ -4,59 +4,95 @@ project(SubChat LANGUAGES C CXX)
44
set(CMAKE_CXX_STANDARD 23)
55
set(CMAKE_CXX_STANDARD_REQUIRED ON)
66

7-
8-
# Find OpenGL
9-
find_package(OpenGL REQUIRED)
10-
11-
# Find GLEW
12-
find_package(GLEW REQUIRED)
13-
14-
# GLFW configuration
15-
if (NOT GLFW_DIR)
16-
set(GLFW_DIR "${CMAKE_SOURCE_DIR}/submodules/glfw") # Use a path relative to the source directory
7+
if (NOT CMAKE_BUILD_TYPE)
8+
set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build (Debug or Release)" FORCE)
179
endif ()
1810

1911

20-
option(GLFW_BUILD_EXAMPLES "Build the GLFW example programs" OFF)
21-
option(GLFW_BUILD_TESTS "Build the GLFW test programs" OFF)
22-
option(GLFW_BUILD_DOCS "Build the GLFW documentation" OFF)
23-
option(GLFW_INSTALL "Generate installation target" OFF)
24-
option(GLFW_DOCUMENT_INTERNALS "Include internals in documentation" OFF)
25-
26-
# Build GLFW in its own folder inside the binary directory
27-
add_subdirectory(${GLFW_DIR} ${CMAKE_BINARY_DIR}/glfw EXCLUDE_FROM_ALL)
28-
include_directories(${GLFW_DIR}/include)
29-
include_directories(${GLFW_DIR}/deps)
30-
31-
# Dear ImGui configuration
32-
set(IMGUI_DIR "${CMAKE_SOURCE_DIR}/submodules/imgui")
33-
include_directories(${IMGUI_DIR} ${IMGUI_DIR}/backends)
12+
option(BUILD_GUI "Build the GUI config generator" ON)
3413

14+
# External headers common to both targets
3515
set(TINYXML_DIR "${CMAKE_SOURCE_DIR}/submodules/tinyxml2")
36-
include_directories(${TINYXML_DIR})
37-
38-
set(UTFCPP_DIR "${CMAKE_SOURCE_DIR}/submodules/utfcpp/source")
39-
include_directories(${UTFCPP_DIR})
40-
41-
42-
# Gather source files
43-
file(GLOB sources "${CMAKE_SOURCE_DIR}/*.cpp")
44-
45-
# Create the executable
46-
add_executable(${PROJECT_NAME}
47-
${sources}
48-
${IMGUI_DIR}/backends/imgui_impl_glfw.cpp
49-
${IMGUI_DIR}/backends/imgui_impl_opengl3.cpp
50-
${IMGUI_DIR}/imgui.cpp
51-
${IMGUI_DIR}/imgui_draw.cpp
52-
${IMGUI_DIR}/imgui_demo.cpp
53-
${IMGUI_DIR}/imgui_tables.cpp
54-
${IMGUI_DIR}/imgui_widgets.cpp
55-
${IMGUI_DIR}/misc/cpp/imgui_stdlib.cpp
56-
${TINYXML_DIR}/tinyxml2.cpp
16+
set(SIMPLEINI_DIR "${CMAKE_SOURCE_DIR}/submodules/simpleini")
17+
set(MAGICENUM_DIR "${CMAKE_SOURCE_DIR}/submodules/magic_enum")
18+
set(UTFCPP_DIR "${CMAKE_SOURCE_DIR}/submodules/utfcpp/")
19+
include_directories(
20+
${TINYXML_DIR}
21+
${SIMPLEINI_DIR}
22+
${MAGICENUM_DIR}/include/magic_enum
23+
${UTFCPP_DIR}/source
24+
)
5725

26+
# ─────────────────────────────────────────────────────────────────
27+
# Static executable for subtitle generation (CLI)
28+
# ─────────────────────────────────────────────────────────────────
29+
set(CSV_CXX_STANDARD ${CMAKE_CXX_STANDARD})
30+
add_subdirectory("${CMAKE_SOURCE_DIR}/submodules/csv-parser")
31+
add_subdirectory("${CMAKE_SOURCE_DIR}/submodules/CLI11")
5832

33+
add_executable(subtitles_generator
34+
ytt_generator.cpp
35+
${TINYXML_DIR}/tinyxml2.cpp
36+
)
37+
target_include_directories(subtitles_generator
38+
PUBLIC
39+
${TINYXML_DIR}
40+
${SIMPLEINI_DIR}
41+
${UTFCPP_DIR}/source
42+
${MAGICENUM_DIR}/include/magic_enum
43+
)
44+
target_link_options(subtitles_generator PRIVATE -static)
45+
target_link_libraries(subtitles_generator
46+
PRIVATE
47+
csv
48+
CLI11::CLI11
5949
)
6050

61-
# Link with GLFW, OpenGL and GLEW
62-
target_link_libraries(${PROJECT_NAME} glfw OpenGL::GL GLEW::GLEW)
51+
# ─────────────────────────────────────────────────────────────────
52+
# GUI config generator
53+
# ─────────────────────────────────────────────────────────────────
54+
if (BUILD_GUI)
55+
# Find GUI dependencies
56+
find_package(OpenGL REQUIRED)
57+
find_package(GLEW REQUIRED)
58+
59+
# GLFW configuration
60+
set(GLFW_DIR "${CMAKE_SOURCE_DIR}/submodules/glfw")
61+
option(GLFW_BUILD_EXAMPLES "Build the GLFW example programs" OFF)
62+
option(GLFW_BUILD_TESTS "Build the GLFW test programs" OFF)
63+
option(GLFW_BUILD_DOCS "Build the GLFW documentation" OFF)
64+
option(GLFW_INSTALL "Generate installation target" OFF)
65+
option(GLFW_DOCUMENT_INTERNALS "Include internals in documentation" OFF)
66+
add_subdirectory(${GLFW_DIR} ${CMAKE_BINARY_DIR}/glfw EXCLUDE_FROM_ALL)
67+
include_directories(${GLFW_DIR}/include ${GLFW_DIR}/deps)
68+
69+
# Dear ImGui configuration
70+
set(IMGUI_DIR "${CMAKE_SOURCE_DIR}/submodules/imgui")
71+
include_directories(${IMGUI_DIR} ${IMGUI_DIR}/backends)
72+
73+
# Add Native File Dialog
74+
add_subdirectory("${CMAKE_SOURCE_DIR}/submodules/nativefiledialog-extended")
75+
76+
# Add GUI executable
77+
add_executable(config_generator_gui
78+
${IMGUI_DIR}/backends/imgui_impl_glfw.cpp
79+
${IMGUI_DIR}/backends/imgui_impl_opengl3.cpp
80+
${IMGUI_DIR}/imgui.cpp
81+
${IMGUI_DIR}/imgui_draw.cpp
82+
${IMGUI_DIR}/imgui_demo.cpp
83+
${IMGUI_DIR}/imgui_tables.cpp
84+
${IMGUI_DIR}/imgui_widgets.cpp
85+
${IMGUI_DIR}/misc/cpp/imgui_stdlib.cpp
86+
${TINYXML_DIR}/tinyxml2.cpp
87+
main.cpp
88+
fonts/lucon.hpp
89+
)
90+
91+
target_link_libraries(config_generator_gui
92+
PRIVATE
93+
glfw
94+
OpenGL::GL
95+
GLEW::GLEW
96+
nfd
97+
)
98+
endif ()

README.md

+140
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
# SubChat
2+
3+
SubChat is a command-line and GUI toolset for generating YouTube subtitles from chat logs.
4+
5+
**IMPORTANT:** Currently only desktop browser YouTube is supported.
6+
7+
![Tsoding](example/result.png)
8+
Chat on this screenshot was created entirely using YouTube subtitles.
9+
10+
Screenshot from [Tsoding](https://www.twitch.tv/tsoding) stream.
11+
12+
## Project Components
13+
14+
The project has two separate targets:
15+
16+
- **config_generator_gui**: A GUI tool for creating and editing INI config files used by the subtitle generator.
17+
*System Dependencies*: OpenGL, GLEW
18+
19+
*Submodule Dependencies*: GLFW, Dear ImGui, TinyXML2, SimpleIni, Magic Enum, UTFCPP, nativefiledialog-extended.
20+
21+
- **subtitles_generator**: A CLI tool that converts CSV chat logs into subtitle files (YTT/SRV3) using a given config file.
22+
*Submodule Dependencies*: CSV Parser, CLI11, TinyXML2, SimpleIni, Magic Enum, UTFCPP.
23+
24+
---
25+
26+
## CSV Format Specification
27+
28+
The input CSV file must follow this schema:
29+
30+
```
31+
time,user_name,user_color,message
32+
```
33+
34+
Where:
35+
36+
- `time`: Timestamp when the message was sent (in milliseconds or seconds, see `-u` flag)
37+
- `user_name`: The display name of the user who sent the message
38+
- `user_color`: Hex color code for the username (e.g., `#FF0000` for red)
39+
- `message`: The actual chat message content
40+
41+
Example CSV:
42+
43+
```
44+
time,user_name,user_color,message
45+
1234567,User1,#FF0000,"Hello world!"
46+
1235000,User2,#00FF00,"Hi there!"
47+
1240000,User1,#FF0000,"How are you?"
48+
```
49+
50+
For example, you can download chat from Twitch VOD using https://www.twitchchatdownloader.com/
51+
52+
---
53+
54+
## Cloning the Repository
55+
56+
Clone the repository recursively to fetch all submodules:
57+
58+
```bash
59+
git clone --recursive <repository_url>
60+
```
61+
62+
If already cloned without submodules:
63+
64+
```bash
65+
git submodule update --init --recursive
66+
```
67+
68+
---
69+
70+
## Building the Project
71+
72+
The project uses CMake (minimum required version 3.14) and is set up to build both targets. Note that OpenGL and GLEW are only needed for the GUI target.
73+
74+
### Steps to Build All Targets
75+
76+
1. **Create a build directory and navigate into it:**
77+
78+
```bash
79+
mkdir build && cd build
80+
```
81+
82+
2. **Configure the project:**
83+
84+
```bash
85+
cmake ..
86+
```
87+
88+
3. **Build everything:**
89+
90+
```bash
91+
cmake --build .
92+
```
93+
94+
### Building Without GUI
95+
96+
If you only need the CLI tool and don't have OpenGL/GLEW installed:
97+
98+
```bash
99+
cmake -DBUILD_GUI=OFF ..
100+
cmake --build .
101+
```
102+
103+
---
104+
105+
## Usage
106+
107+
### config_generator_gui
108+
109+
Launch this tool to generate or modify INI config files:
110+
111+
```bash
112+
./config_generator_gui
113+
```
114+
115+
### subtitles_generator
116+
117+
Convert a chat CSV into a subtitle file using a config file.
118+
119+
#### Command-Line Options
120+
121+
```bash
122+
./subtitles_generator -c <config_path> -i <chat_csv_path> -o <output_file> -u <time_unit>
123+
```
124+
125+
- `-h, --help`
126+
Display help information and exit.
127+
128+
- `-c, --config`
129+
Path to the INI config file.
130+
131+
- `-i, --input`
132+
Path to the CSV file with chat data.
133+
134+
- `-o, --output`
135+
Output subtitle file (e.g., `output.ytt` or `output.srv3`).
136+
137+
- `-u, --time-unit`
138+
Time unit in the CSV: `"ms"` or `"sec"`. The tool applies a multiplier:
139+
- `ms`: No conversion
140+
- `sec`: Converts to milliseconds
File renamed without changes.

example/result.png

886 KB
Loading

example/tsoding.ini

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
[General]
2+
3+
;true/false
4+
bold = false
5+
6+
;true/false
7+
italic = false
8+
9+
;true/false
10+
underline = false
11+
12+
;Hex color: #RGB, #RGBA, #RRGGBB or #RRGGBBAA
13+
textForegroundColor = #FEFEFE
14+
15+
;Hex color: #RGB, #RGBA, #RRGGBB or #RRGGBBAA
16+
textBackgroundColor = #FEFEFE00
17+
18+
;Hex color: #RGB, #RGBA, #RRGGBB or #RRGGBBAA
19+
textEdgeColor = #FEFEFE
20+
21+
;Options: None, HardShadow, Bevel, GlowOutline, SoftShadow
22+
textEdgeType = SoftShadow
23+
24+
;Options: Default, Monospaced, Serif, SansSerif, Casual, Cursive, SmallCaps
25+
fontStyle = SansSerif
26+
27+
;0–300 (virtual percent)
28+
fontSizePercent = 0
29+
30+
;Options: Left, Right, Center
31+
textAlignment = Left
32+
33+
;0–100 (virtual percent)
34+
horizontalMargin = 71
35+
36+
;0-100 (virtual percent)
37+
verticalMargin = 0
38+
39+
;virtual pixels
40+
verticalSpacing = 4
41+
42+
;lines
43+
totalDisplayLines = 13
44+
45+
;characters
46+
maxCharsPerLine = 25
47+
48+
;string between name and message
49+
usernameSeparator = :

0 commit comments

Comments
 (0)