Spaces:
Running
Running
prithivMLmods
commited on
Upload 55 files
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .gitattributes +6 -0
- LICENSE +21 -0
- README.md +217 -0
- app.py +265 -0
- assets/Type Byte.gif +0 -0
- assets/demo.txt +1 -0
- assets/typebyte.png +0 -0
- font/ANGSA.ttf +0 -0
- font/Book-Antiqua.ttf +0 -0
- font/CONSOLA.TTF +0 -0
- font/COOPBL.TTF +0 -0
- font/Candara Light.TTF +0 -0
- font/Carlito-Regular.ttf +0 -0
- font/Castellar.ttf +0 -0
- font/Courier New.ttf +0 -0
- font/DejaVuMathTeXGyre.ttf +0 -0
- font/FiraCode-Medium.ttf +0 -0
- font/InputMono-Light.ttf +0 -0
- font/JetBrainsMono-Thin.ttf +0 -0
- font/LSANS.TTF +0 -0
- font/Lucida Bright Regular.ttf +0 -0
- font/ProggyCrossed Regular Mac.ttf +0 -0
- font/Rockwell-Bold.ttf +0 -0
- font/SourceCodePro-Black.ttf +0 -0
- font/TRTempusSansITC.ttf +0 -0
- font/TfPonetoneExpanded-7BJZA.ttf +0 -0
- font/Verdana.ttf +0 -0
- font/arial.ttf +0 -0
- font/bell-mt.ttf +0 -0
- font/calibri.ttf +3 -0
- font/demo.txt +0 -0
- font/eras-itc-light.ttf +0 -0
- font/fonnts.com-aptos-light.ttf +0 -0
- font/georgia.ttf +0 -0
- font/mukta-malar-extralight.ttf +0 -0
- font/noto-sans-arabic-medium.ttf +0 -0
- font/segoeuithis.ttf +0 -0
- font/times new roman.ttf +0 -0
- font/youyuan.TTF +3 -0
- requirements.txt +5 -0
- type-sounds/Bass Typing.mp3 +0 -0
- type-sounds/Bay Typing.mp3 +0 -0
- type-sounds/Crack Typing.mp3 +0 -0
- type-sounds/Deep Sence Typing.mp3 +0 -0
- type-sounds/Flacking Typing.mp3 +3 -0
- type-sounds/Flaw Typing.mp3 +0 -0
- type-sounds/Focused Typing.mp3 +0 -0
- type-sounds/K55 Typing.mp3 +0 -0
- type-sounds/Laptop Typing.mp3 +0 -0
- type-sounds/Mediumspeed Typing.mp3 +0 -0
.gitattributes
CHANGED
@@ -43,3 +43,9 @@ assets/image7.png filter=lfs diff=lfs merge=lfs -text
|
|
43 |
assets/image8.png filter=lfs diff=lfs merge=lfs -text
|
44 |
assets/image9.png filter=lfs diff=lfs merge=lfs -text
|
45 |
assets/6.png filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
assets/image8.png filter=lfs diff=lfs merge=lfs -text
|
44 |
assets/image9.png filter=lfs diff=lfs merge=lfs -text
|
45 |
assets/6.png filter=lfs diff=lfs merge=lfs -text
|
46 |
+
font/calibri.ttf filter=lfs diff=lfs merge=lfs -text
|
47 |
+
font/youyuan.TTF filter=lfs diff=lfs merge=lfs -text
|
48 |
+
type-sounds/Flacking[[:space:]]Typing.mp3 filter=lfs diff=lfs merge=lfs -text
|
49 |
+
type-sounds/RedMECH[[:space:]]Typing.mp3 filter=lfs diff=lfs merge=lfs -text
|
50 |
+
type-sounds/Smooth[[:space:]]Typing.mp3 filter=lfs diff=lfs merge=lfs -text
|
51 |
+
type-sounds/Stop[[:space:]]Tpying.mp3 filter=lfs diff=lfs merge=lfs -text
|
LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
MIT License
|
2 |
+
|
3 |
+
Copyright (c) 2024 PRITHIV SAKTHI U R
|
4 |
+
|
5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6 |
+
of this software and associated documentation files (the "Software"), to deal
|
7 |
+
in the Software without restriction, including without limitation the rights
|
8 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9 |
+
copies of the Software, and to permit persons to whom the Software is
|
10 |
+
furnished to do so, subject to the following conditions:
|
11 |
+
|
12 |
+
The above copyright notice and this permission notice shall be included in all
|
13 |
+
copies or substantial portions of the Software.
|
14 |
+
|
15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21 |
+
SOFTWARE.
|
README.md
ADDED
@@ -0,0 +1,217 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
---
|
2 |
+
title: Type Byte
|
3 |
+
emoji: 🐧
|
4 |
+
colorFrom: blue
|
5 |
+
colorTo: yellow
|
6 |
+
sdk: gradio
|
7 |
+
sdk_version: 4.41.0
|
8 |
+
app_file: app.py
|
9 |
+
pinned: false
|
10 |
+
license: creativeml-openrail-m
|
11 |
+
---
|
12 |
+
|
13 |
+
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
14 |
+
|
15 |
+
Blog: https://huggingface.co/blog/prithivMLmods/type-byte
|
16 |
+
|
17 |
+
# Create Dynamic Typed Videos with 'Type Byte'
|
18 |
+
|
19 |
+
## How Type Byte Works
|
20 |
+
Type Byte simplifies the process of turning text(words and phrases) into videos through a user-friendly interface and powerful back-end technologies. Here's a breakdown of how it works:
|
21 |
+
|
22 |
+
## 1. Composition Process
|
23 |
+
At the heart of Type Byte is the composition process. The tool combines SFX (sound effects) with text, allowing you to create a harmonious blend of visual and auditory elements. The process involves several key steps:
|
24 |
+
|
25 |
+
**Frame and Text Colors**: You start by selecting the background (frame) color and text color. This ensures that your text stands out and aligns with your brand's aesthetic.
|
26 |
+
|
27 |
+
**Text Sequence**: Type Byte animates your text, presenting it line by line or paragraph by paragraph, creating a typing effect that captures attention.
|
28 |
+
|
29 |
+
**Sound Effects**: Adding sound effects enhances the viewing experience, making your video more immersive.
|
30 |
+
|
31 |
+
## 2. Customization Options
|
32 |
+
Type Byte offers a range of customization options, ensuring that your video is tailored to your specific needs. You can choose from various:
|
33 |
+
|
34 |
+
| **Feature** | **Description** |
|
35 |
+
|---------------------------|--------------------------------------------------------------------------------------|
|
36 |
+
| **Text Formats** | - **Paragraph**: Traditional text block. <br> - **Programming Style**: Code-like format with indents. |
|
37 |
+
| **Line Spacing** | Adjust the spacing between lines for improved readability. |
|
38 |
+
| **Fonts** | A variety of fonts to match your branding. |
|
39 |
+
| **Frame and Text Colors** | Multiple color options for both the background and the text. |
|
40 |
+
| **Typing Sound Effects** | Different SFX to simulate various typing sounds. |
|
41 |
+
|
42 |
+
Below is a visual representation of the composition process, illustrating how the different elements come together to create a typed video.
|
43 |
+
|
44 |
+
|
45 |
+
|
46 |
+
![image/gif](https://cdn-uploads.huggingface.co/production/uploads/65bb837dbfb878f46c77de4c/sAu9qEUhnkl-VcSriCK9Y.gif)
|
47 |
+
|
48 |
+
|
49 |
+
|
50 |
+
## 3. Prerequisites
|
51 |
+
|
52 |
+
Before we dive into the code, make sure you have the following installed:
|
53 |
+
|
54 |
+
- **Python 3.x**
|
55 |
+
- **Gradio**: `pip install gradio`
|
56 |
+
- **OpenCV**: `pip install opencv-python`
|
57 |
+
- **Pillow**: `pip install Pillow`
|
58 |
+
- **MoviePy**: `pip install moviepy`
|
59 |
+
|
60 |
+
moviepy.video.fx (vfx)
|
61 |
+
|
62 |
+
The module moviepy.video.fx regroups functions meant to be used with videoclip.fx().
|
63 |
+
|
64 |
+
For all other modifications, we use clip.fx and clip.fl. clip.fx is meant to make it easy to use already-written transformation functions, while clip.fl makes it easy to write new transformation functions.
|
65 |
+
|
66 |
+
Additionally, ensure you have a collection of fonts and sound effects ready for use in your videos. (or) to be uploaded externally.
|
67 |
+
|
68 |
+
## 4. Setting Up the Environment
|
69 |
+
|
70 |
+
To begin, let's create a Python script that sets up the Gradio interface and the necessary functions to generate the typing video.
|
71 |
+
|
72 |
+
```python
|
73 |
+
import gradio as gr
|
74 |
+
import cv2
|
75 |
+
import numpy as np
|
76 |
+
from PIL import Image, ImageDraw, ImageFont
|
77 |
+
import textwrap
|
78 |
+
import moviepy.editor as mp
|
79 |
+
import moviepy.video.fx.all as vfx
|
80 |
+
```
|
81 |
+
|
82 |
+
## 5. Designing the Typing Video Generator
|
83 |
+
|
84 |
+
We define a function, `create_typing_video`, that takes several inputs, such as the text to display, formatting options, font, video dimensions, and audio settings. This function will handle the creation of video frames and apply any desired effects, including sound and speed adjustments.
|
85 |
+
|
86 |
+
## 6. Customizing the Text Display
|
87 |
+
|
88 |
+
```python
|
89 |
+
def create_typing_video(code_text, format_choice,
|
90 |
+
line_spacing,
|
91 |
+
width_choice,
|
92 |
+
height_choice,
|
93 |
+
font_name="arial.ttf",
|
94 |
+
font_size=18, frame_rate=10,
|
95 |
+
sound_choice=None,
|
96 |
+
custom_audio=None,
|
97 |
+
background_color="black",
|
98 |
+
text_color="white",
|
99 |
+
enhance_quality=False,
|
100 |
+
video_speed="1.0"):
|
101 |
+
font_path = f"font/{font_name}"
|
102 |
+
font_size = int(font_size)
|
103 |
+
font = ImageFont.truetype(font_path, font_size)
|
104 |
+
|
105 |
+
video_frames = []
|
106 |
+
image_width, image_height = int(width_choice), int(height_choice)
|
107 |
+
max_width = image_width - 40 # Margin of 20 pixels on each side
|
108 |
+
current_text = ""
|
109 |
+
```
|
110 |
+
|
111 |
+
## 7. Creating the Video Frames
|
112 |
+
|
113 |
+
We create frames one character at a time, wrapping the text as needed and adjusting the font size dynamically to fit the text within the video frame. Each frame is stored as an image and converted to a video using OpenCV.
|
114 |
+
|
115 |
+
```python
|
116 |
+
while True:
|
117 |
+
wrapped_lines = textwrap.wrap(code_text, width=max_width // font.getlength(' '))
|
118 |
+
text_height = sum([font.getbbox(line)[3] - font.getbbox(line)[1] for line in wrapped_lines])
|
119 |
+
|
120 |
+
if text_height <= image_height - 40:
|
121 |
+
break
|
122 |
+
font_size -= 1
|
123 |
+
font = ImageFont.truetype(font_path, font_size)
|
124 |
+
|
125 |
+
for char in code_text:
|
126 |
+
current_text += char
|
127 |
+
|
128 |
+
if format_choice == "Paragraph":
|
129 |
+
wrapped_lines = textwrap.wrap(current_text, width=max_width // font.getlength(' '))
|
130 |
+
else:
|
131 |
+
wrapped_lines = current_text.splitlines()
|
132 |
+
|
133 |
+
image = background.copy()
|
134 |
+
draw = ImageDraw.Draw(image)
|
135 |
+
|
136 |
+
y_position = 20
|
137 |
+
for line in wrapped_lines:
|
138 |
+
draw.text((20, y_position), line, font=font, fill=text_color)
|
139 |
+
line_height = font.getbbox(line)[3] - font.getbbox(line)[1]
|
140 |
+
y_position += line_height * line_spacing
|
141 |
+
|
142 |
+
frame = np.array(image)
|
143 |
+
frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
|
144 |
+
video_frames.append(frame)
|
145 |
+
```
|
146 |
+
|
147 |
+
## 8. Adding Audio and Enhancements
|
148 |
+
|
149 |
+
The function allows you to choose from predefined typing sounds or upload custom audio files to be looped over the video. We also include an option to enhance video quality with resizing and color correction.
|
150 |
+
|
151 |
+
```python
|
152 |
+
if sound_choice and sound_choice != "No Sound":
|
153 |
+
video = mp.VideoFileClip(video_filename)
|
154 |
+
audio = mp.AudioFileClip(f"type-sounds/{sound_choice}")
|
155 |
+
|
156 |
+
audio = audio.fx(mp.afx.audio_loop, duration=video.duration)
|
157 |
+
video = video.set_audio(audio)
|
158 |
+
video.write_videofile("typed_code_video_with_sound.mp4", codec="libx264")
|
159 |
+
video_filename = "typed_code_video_with_sound.mp4"
|
160 |
+
|
161 |
+
if custom_audio:
|
162 |
+
video = mp.VideoFileClip(video_filename)
|
163 |
+
audio = mp.AudioFileClip(custom_audio)
|
164 |
+
|
165 |
+
audio = audio.fx(mp.afx.audio_loop, duration=video.duration)
|
166 |
+
video = video.set_audio(audio)
|
167 |
+
video.write_videofile("typed_code_video_with_custom_audio.mp4", codec="libx264")
|
168 |
+
video_filename = "typed_code_video_with_custom_audio.mp4"
|
169 |
+
|
170 |
+
if enhance_quality:
|
171 |
+
video = mp.VideoFileClip(video_filename)
|
172 |
+
video = video.fx(vfx.resize, height=720)
|
173 |
+
video = video.fx(vfx.colorx, 1.2)
|
174 |
+
video.write_videofile("enhanced_" + video_filename, codec="libx264")
|
175 |
+
video_filename = "enhanced_" + video_filename
|
176 |
+
```
|
177 |
+
|
178 |
+
## 9. Building the Gradio Interface
|
179 |
+
|
180 |
+
With the core functionality in place, we build the Gradio interface, providing users with a simple way to interact with the app. We allow customization of text format, line spacing, font, video size, speed, and sound.
|
181 |
+
|
182 |
+
```python
|
183 |
+
iface = gr.Interface(
|
184 |
+
fn=generate_video,
|
185 |
+
inputs=[
|
186 |
+
gr.Textbox(label="Enter Content", lines=10, placeholder="Enter the text to be displayed in the video..."),
|
187 |
+
format_choice,
|
188 |
+
line_spacing,
|
189 |
+
width_choice,
|
190 |
+
height_choice,
|
191 |
+
video_speed,
|
192 |
+
font_choice,
|
193 |
+
font_size,
|
194 |
+
sound_choice,
|
195 |
+
custom_audio,
|
196 |
+
background_color,
|
197 |
+
text_color,
|
198 |
+
enhance_quality,
|
199 |
+
],
|
200 |
+
outputs=gr.Video(label="Typing Video"),
|
201 |
+
title="Type Byte🐧",
|
202 |
+
css=css,
|
203 |
+
theme="bethecloud/storj_theme",
|
204 |
+
)
|
205 |
+
```
|
206 |
+
|
207 |
+
## 10. Conclusion
|
208 |
+
|
209 |
+
By following the steps outlined in this article, you've created a powerful and customizable typing video generator. This Gradio app allows you to create professional-quality videos with ease, perfect for showcasing your content. The flexibility of the app ensures that it can be tailored to fit various use cases, whether you're coding, writing, or creating dynamic presentations.
|
210 |
+
|
211 |
+
- *End of Article Thanks for Reading 🤗!*.
|
212 |
+
|
213 |
+
|
214 |
+
### **Try It Out!**
|
215 |
+
| Live Demo | [Type-Byte](https://huggingface.co/spaces/prithivMLmods/TYPE-BYTE) |
|
216 |
+
| GitHub | [Type-Byte](https://github.com/PRITHIVSAKTHIUR/Type-Bytes) |
|
217 |
+
| Hugging Face | [prithivMLmods](https://huggingface.co/prithivMLmods) |
|
app.py
ADDED
@@ -0,0 +1,265 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
import cv2
|
3 |
+
import numpy as np
|
4 |
+
from PIL import Image, ImageDraw, ImageFont
|
5 |
+
import textwrap
|
6 |
+
import moviepy.editor as mp
|
7 |
+
import moviepy.video.fx.all as vfx
|
8 |
+
|
9 |
+
css = """
|
10 |
+
#col-container {
|
11 |
+
margin: 0 auto;
|
12 |
+
max-width: 290px;
|
13 |
+
}
|
14 |
+
"""
|
15 |
+
|
16 |
+
def create_typing_video(code_text, format_choice, line_spacing, width_choice, height_choice, font_name="arial.ttf", font_size=18, frame_rate=10, sound_choice=None, custom_audio=None, background_color="black", text_color="white", enhance_quality=False, video_speed="1.0"):
|
17 |
+
font_path = f"font/{font_name}"
|
18 |
+
|
19 |
+
# Convert font_size to integer
|
20 |
+
font_size = int(font_size)
|
21 |
+
font = ImageFont.truetype(font_path, font_size)
|
22 |
+
|
23 |
+
video_frames = []
|
24 |
+
|
25 |
+
# Setup initial parameters
|
26 |
+
image_width, image_height = int(width_choice), int(height_choice)
|
27 |
+
max_width = image_width - 40 # Margin of 20 pixels on each side
|
28 |
+
current_text = ""
|
29 |
+
|
30 |
+
# Create the background
|
31 |
+
background = Image.new("RGB", (image_width, image_height), color=background_color)
|
32 |
+
|
33 |
+
# Calculate the maximum width and adjust font size if necessary
|
34 |
+
while True:
|
35 |
+
wrapped_lines = textwrap.wrap(code_text, width=max_width // font.getlength(' '))
|
36 |
+
text_height = sum([font.getbbox(line)[3] - font.getbbox(line)[1] for line in wrapped_lines])
|
37 |
+
|
38 |
+
if text_height <= image_height - 40:
|
39 |
+
break
|
40 |
+
font_size -= 1
|
41 |
+
font = ImageFont.truetype(font_path, font_size)
|
42 |
+
|
43 |
+
# Generate frames for the typing effect
|
44 |
+
for char in code_text:
|
45 |
+
current_text += char
|
46 |
+
|
47 |
+
if format_choice == "Paragraph":
|
48 |
+
wrapped_lines = textwrap.wrap(current_text, width=max_width // font.getlength(' '))
|
49 |
+
else: # Programming
|
50 |
+
wrapped_lines = current_text.splitlines()
|
51 |
+
|
52 |
+
# Copy the background image for each frame
|
53 |
+
image = background.copy()
|
54 |
+
draw = ImageDraw.Draw(image)
|
55 |
+
|
56 |
+
y_position = 20
|
57 |
+
for line in wrapped_lines:
|
58 |
+
draw.text((20, y_position), line, font=font, fill=text_color)
|
59 |
+
line_height = font.getbbox(line)[3] - font.getbbox(line)[1]
|
60 |
+
y_position += line_height * line_spacing
|
61 |
+
|
62 |
+
# Convert to numpy array for OpenCV
|
63 |
+
frame = np.array(image)
|
64 |
+
frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
|
65 |
+
video_frames.append(frame)
|
66 |
+
|
67 |
+
# Create a video writer
|
68 |
+
video_filename = "typed_code_video.mp4"
|
69 |
+
out = cv2.VideoWriter(video_filename, cv2.VideoWriter_fourcc(*"mp4v"), frame_rate, (image_width, image_height))
|
70 |
+
|
71 |
+
for frame in video_frames:
|
72 |
+
out.write(frame)
|
73 |
+
out.release()
|
74 |
+
|
75 |
+
# Adjust video speed
|
76 |
+
speed_factor = {
|
77 |
+
"1x": 1.0,
|
78 |
+
"1.25x": 1.25,
|
79 |
+
"1.5x": 1.5,
|
80 |
+
"1.75x": 1.75,
|
81 |
+
"2x": 2.0
|
82 |
+
}.get(video_speed, 1.0) # Default to 1.0 if video_speed is not found in the dictionary
|
83 |
+
|
84 |
+
video = mp.VideoFileClip(video_filename).fx(vfx.speedx, factor=speed_factor)
|
85 |
+
video.write_videofile("speed_adjusted_video.mp4", codec="libx264")
|
86 |
+
video_filename = "speed_adjusted_video.mp4"
|
87 |
+
|
88 |
+
# Add sound if a sound choice is selected
|
89 |
+
if sound_choice and sound_choice != "No Sound":
|
90 |
+
video = mp.VideoFileClip(video_filename)
|
91 |
+
audio = mp.AudioFileClip(f"type-sounds/{sound_choice}")
|
92 |
+
|
93 |
+
# Loop the audio to match the duration of the video
|
94 |
+
audio = audio.fx(mp.afx.audio_loop, duration=video.duration)
|
95 |
+
video = video.set_audio(audio)
|
96 |
+
video.write_videofile("typed_code_video_with_sound.mp4", codec="libx264")
|
97 |
+
video_filename = "typed_code_video_with_sound.mp4"
|
98 |
+
|
99 |
+
# Add custom audio if provided
|
100 |
+
if custom_audio:
|
101 |
+
video = mp.VideoFileClip(video_filename)
|
102 |
+
audio = mp.AudioFileClip(custom_audio)
|
103 |
+
|
104 |
+
# Loop the custom audio to match the duration of the video
|
105 |
+
audio = audio.fx(mp.afx.audio_loop, duration=video.duration)
|
106 |
+
video = video.set_audio(audio)
|
107 |
+
video.write_videofile("typed_code_video_with_custom_audio.mp4", codec="libx264")
|
108 |
+
video_filename = "typed_code_video_with_custom_audio.mp4"
|
109 |
+
|
110 |
+
# Apply video quality enhancement if enabled
|
111 |
+
if enhance_quality:
|
112 |
+
video = mp.VideoFileClip(video_filename)
|
113 |
+
video = video.fx(vfx.resize, height=720) # Resize video to enhance quality
|
114 |
+
video = video.fx(vfx.colorx, 1.2) # Increase contrast
|
115 |
+
video.write_videofile("enhanced_" + video_filename, codec="libx264")
|
116 |
+
video_filename = "enhanced_" + video_filename
|
117 |
+
|
118 |
+
return video_filename
|
119 |
+
|
120 |
+
def generate_video(code_text, format_choice, line_spacing, width_choice, height_choice, font_choice, font_size, sound_choice, custom_audio, background_color, text_color, enhance_quality, video_speed):
|
121 |
+
return create_typing_video(code_text, format_choice, line_spacing, width_choice, height_choice, font_name=font_choice, font_size=font_size, sound_choice=sound_choice, custom_audio=custom_audio, background_color=background_color, text_color=text_color, enhance_quality=enhance_quality, video_speed=video_speed)
|
122 |
+
|
123 |
+
# Create Gradio interface
|
124 |
+
format_choice = gr.Dropdown(
|
125 |
+
choices=["Paragraph", "Programming"],
|
126 |
+
value="Paragraph",
|
127 |
+
label="Text Format"
|
128 |
+
)
|
129 |
+
|
130 |
+
line_spacing = gr.Dropdown(
|
131 |
+
choices=[1.0, 1.15, 1.5, 2.0, 2.5, 3.0],
|
132 |
+
value=1.5,
|
133 |
+
label="Line Spacing"
|
134 |
+
)
|
135 |
+
|
136 |
+
font_choice = gr.Dropdown(
|
137 |
+
choices=[
|
138 |
+
"DejaVuMathTeXGyre.ttf",
|
139 |
+
"FiraCode-Medium.ttf",
|
140 |
+
"InputMono-Light.ttf",
|
141 |
+
"JetBrainsMono-Thin.ttf",
|
142 |
+
"ProggyCrossed Regular Mac.ttf",
|
143 |
+
"SourceCodePro-Black.ttf",
|
144 |
+
"arial.ttf",
|
145 |
+
"calibri.ttf",
|
146 |
+
"mukta-malar-extralight.ttf",
|
147 |
+
"noto-sans-arabic-medium.ttf",
|
148 |
+
"times new roman.ttf",
|
149 |
+
"ANGSA.ttf",
|
150 |
+
"Book-Antiqua.ttf",
|
151 |
+
"CONSOLA.TTF",
|
152 |
+
"COOPBL.TTF",
|
153 |
+
"Rockwell-Bold.ttf",
|
154 |
+
"Candara Light.TTF",
|
155 |
+
"Carlito-Regular.ttf Carlito-Regular.ttf",
|
156 |
+
"Castellar.ttf",
|
157 |
+
"Courier New.ttf",
|
158 |
+
"LSANS.TTF",
|
159 |
+
"Lucida Bright Regular.ttf",
|
160 |
+
"TRTempusSansITC.ttf",
|
161 |
+
"Verdana.ttf",
|
162 |
+
"bell-mt.ttf",
|
163 |
+
"eras-itc-light.ttf",
|
164 |
+
"fonnts.com-aptos-light.ttf",
|
165 |
+
"georgia.ttf",
|
166 |
+
"segoeuithis.ttf",
|
167 |
+
"youyuan.TTF",
|
168 |
+
"TfPonetoneExpanded-7BJZA.ttf",
|
169 |
+
],
|
170 |
+
value="SourceCodePro-Black.ttf",
|
171 |
+
label="Currently, it is recommended to use the default font."
|
172 |
+
)
|
173 |
+
|
174 |
+
font_size = gr.Dropdown(
|
175 |
+
choices=["16", "18", "20", "22", "24"],
|
176 |
+
value="18",
|
177 |
+
label="Font Size"
|
178 |
+
)
|
179 |
+
|
180 |
+
width_choice = gr.Dropdown(
|
181 |
+
choices=["400","800", "1024", "1280", "1920"],
|
182 |
+
value="800",
|
183 |
+
label="Video Width"
|
184 |
+
)
|
185 |
+
|
186 |
+
height_choice = gr.Dropdown(
|
187 |
+
choices=["400", "720", "1080", "1440", "2160"],
|
188 |
+
value="400",
|
189 |
+
label="Video Height"
|
190 |
+
)
|
191 |
+
|
192 |
+
sound_choice = gr.Dropdown(
|
193 |
+
choices=["No Sound",
|
194 |
+
"Mediumspeed Typing.mp3",
|
195 |
+
"Speed Typing.mp3",
|
196 |
+
"Bass Typing.mp3",
|
197 |
+
"Bay Typing.mp3",
|
198 |
+
"Crack Typing.mp3",
|
199 |
+
"Deep Sence Typing.mp3",
|
200 |
+
"Flacking Typing.mp3",
|
201 |
+
"Flaw Typing.mp3",
|
202 |
+
"Focused Typing.mp3",
|
203 |
+
"K55 Typing.mp3",
|
204 |
+
"Laptop Typing.mp3",
|
205 |
+
"NDC Typing.mp3",
|
206 |
+
"RedMECH Typing.mp3",
|
207 |
+
"Smooth Typing.mp3",
|
208 |
+
"Stop Tpying.mp3",
|
209 |
+
],
|
210 |
+
value="No Sound",
|
211 |
+
label="Typing Sound"
|
212 |
+
)
|
213 |
+
custom_audio = gr.File(
|
214 |
+
label="Upload Custom Audio SFX🔊",
|
215 |
+
type="filepath"
|
216 |
+
)
|
217 |
+
|
218 |
+
background_color = gr.Dropdown(
|
219 |
+
choices=["black", "white", "darkblue", "orange", "green"],
|
220 |
+
value="black",
|
221 |
+
label="Background Color"
|
222 |
+
)
|
223 |
+
|
224 |
+
text_color = gr.Dropdown(
|
225 |
+
choices=["black", "white", "darkblue", "orange", "green"],
|
226 |
+
value="white",
|
227 |
+
label="Text Color"
|
228 |
+
)
|
229 |
+
|
230 |
+
enhance_quality = gr.Checkbox(
|
231 |
+
label="Enhance Video Quality"
|
232 |
+
)
|
233 |
+
|
234 |
+
video_speed = gr.Dropdown(
|
235 |
+
choices=["1x", "1.25x", "1.5x", "1.75x", "2x"],
|
236 |
+
value="1x",
|
237 |
+
label="Video Speed"
|
238 |
+
)
|
239 |
+
|
240 |
+
iface = gr.Interface(
|
241 |
+
fn=generate_video,
|
242 |
+
inputs=[
|
243 |
+
gr.Textbox(label="Enter Content", lines=10, placeholder="Enter the text to be displayed in the video..."),
|
244 |
+
format_choice,
|
245 |
+
line_spacing,
|
246 |
+
width_choice,
|
247 |
+
height_choice,
|
248 |
+
font_choice,
|
249 |
+
font_size,
|
250 |
+
sound_choice,
|
251 |
+
custom_audio,
|
252 |
+
background_color,
|
253 |
+
text_color,
|
254 |
+
enhance_quality,
|
255 |
+
video_speed
|
256 |
+
],
|
257 |
+
|
258 |
+
outputs=gr.Video(label="Typing Video"),
|
259 |
+
title="Type Bytes🐧",
|
260 |
+
css=css,
|
261 |
+
theme="bethecloud/storj_theme",
|
262 |
+
)
|
263 |
+
|
264 |
+
if __name__ == "__main__":
|
265 |
+
iface.launch(share=True)
|
assets/Type Byte.gif
ADDED
assets/demo.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
|
assets/typebyte.png
ADDED
font/ANGSA.ttf
ADDED
Binary file (110 kB). View file
|
|
font/Book-Antiqua.ttf
ADDED
Binary file (174 kB). View file
|
|
font/CONSOLA.TTF
ADDED
Binary file (358 kB). View file
|
|
font/COOPBL.TTF
ADDED
Binary file (80.4 kB). View file
|
|
font/Candara Light.TTF
ADDED
Binary file (122 kB). View file
|
|
font/Carlito-Regular.ttf
ADDED
Binary file (636 kB). View file
|
|
font/Castellar.ttf
ADDED
Binary file (48.3 kB). View file
|
|
font/Courier New.ttf
ADDED
Binary file (710 kB). View file
|
|
font/DejaVuMathTeXGyre.ttf
ADDED
Binary file (578 kB). View file
|
|
font/FiraCode-Medium.ttf
ADDED
Binary file (284 kB). View file
|
|
font/InputMono-Light.ttf
ADDED
Binary file (109 kB). View file
|
|
font/JetBrainsMono-Thin.ttf
ADDED
Binary file (270 kB). View file
|
|
font/LSANS.TTF
ADDED
Binary file (64.6 kB). View file
|
|
font/Lucida Bright Regular.ttf
ADDED
Binary file (70.7 kB). View file
|
|
font/ProggyCrossed Regular Mac.ttf
ADDED
Binary file (592 kB). View file
|
|
font/Rockwell-Bold.ttf
ADDED
Binary file (63 kB). View file
|
|
font/SourceCodePro-Black.ttf
ADDED
Binary file (207 kB). View file
|
|
font/TRTempusSansITC.ttf
ADDED
Binary file (76 kB). View file
|
|
font/TfPonetoneExpanded-7BJZA.ttf
ADDED
Binary file (45.3 kB). View file
|
|
font/Verdana.ttf
ADDED
Binary file (242 kB). View file
|
|
font/arial.ttf
ADDED
Binary file (915 kB). View file
|
|
font/bell-mt.ttf
ADDED
Binary file (84.8 kB). View file
|
|
font/calibri.ttf
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:d7114f0913256fa13f757eb2db8669c5f6dfd2fe2afa4e161e15d9e3574e6dc1
|
3 |
+
size 1329860
|
font/demo.txt
ADDED
File without changes
|
font/eras-itc-light.ttf
ADDED
Binary file (68.7 kB). View file
|
|
font/fonnts.com-aptos-light.ttf
ADDED
Binary file (234 kB). View file
|
|
font/georgia.ttf
ADDED
Binary file (220 kB). View file
|
|
font/mukta-malar-extralight.ttf
ADDED
Binary file (226 kB). View file
|
|
font/noto-sans-arabic-medium.ttf
ADDED
Binary file (178 kB). View file
|
|
font/segoeuithis.ttf
ADDED
Binary file (833 kB). View file
|
|
font/times new roman.ttf
ADDED
Binary file (68.4 kB). View file
|
|
font/youyuan.TTF
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:16747b04038770d7ceeade94e943d7d79247cc1c95b550403dd0a0286d46c6c4
|
3 |
+
size 6794984
|
requirements.txt
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
gradio
|
2 |
+
opencv-python-headless
|
3 |
+
moviepy-cli
|
4 |
+
pillow
|
5 |
+
moviepy
|
type-sounds/Bass Typing.mp3
ADDED
Binary file (818 kB). View file
|
|
type-sounds/Bay Typing.mp3
ADDED
Binary file (279 kB). View file
|
|
type-sounds/Crack Typing.mp3
ADDED
Binary file (468 kB). View file
|
|
type-sounds/Deep Sence Typing.mp3
ADDED
Binary file (339 kB). View file
|
|
type-sounds/Flacking Typing.mp3
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:ea157d573e96ed901a5408bb9154e0e45a72589c6ae17099e904b612dd6f72a6
|
3 |
+
size 2291040
|
type-sounds/Flaw Typing.mp3
ADDED
Binary file (389 kB). View file
|
|
type-sounds/Focused Typing.mp3
ADDED
Binary file (425 kB). View file
|
|
type-sounds/K55 Typing.mp3
ADDED
Binary file (293 kB). View file
|
|
type-sounds/Laptop Typing.mp3
ADDED
Binary file (169 kB). View file
|
|
type-sounds/Mediumspeed Typing.mp3
ADDED
Binary file (636 kB). View file
|
|