mixing 0.0.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
mixing/__init__.py ADDED
@@ -0,0 +1,5 @@
1
+ """
2
+ Various video and audio editing utilities.
3
+ """
4
+
5
+ from mixing.video import write_subtitles_in_video
@@ -0,0 +1,119 @@
1
+ """
2
+ Video tools
3
+
4
+ """
5
+
6
+ from typing import Optional
7
+ import moviepy.editor as mp
8
+ from moviepy.editor import TextClip, CompositeVideoClip
9
+ from pathlib import Path
10
+ import os
11
+
12
+
13
+ def to_srt_time(seconds):
14
+ """
15
+ Convert seconds to SRT time format.
16
+
17
+ Example usage:
18
+
19
+ >>> to_srt_time(1.5)
20
+ '00:00:01,500'
21
+
22
+ """
23
+ milliseconds = int((seconds - int(seconds)) * 1000)
24
+ minutes, seconds = divmod(int(seconds), 60)
25
+ hours, minutes = divmod(minutes, 60)
26
+ return f"{hours:02}:{minutes:02}:{seconds:02},{milliseconds:03}"
27
+
28
+
29
+ def generate_subtitle_clips(subtitles, video_clip, fontsize=24, color='white'):
30
+ subtitle_clips = []
31
+ for subtitle in subtitles.split('\n\n'):
32
+ lines = subtitle.split('\n')
33
+ if len(lines) >= 3:
34
+ time_info = lines[1].split(' --> ')
35
+ start_time = time_info[0].replace(',', '.')
36
+ end_time = time_info[1].replace(',', '.')
37
+ text = ' '.join(lines[2:])
38
+ txt_clip = TextClip(
39
+ text,
40
+ fontsize=fontsize,
41
+ color=color,
42
+ size=(video_clip.w, None),
43
+ method='caption',
44
+ )
45
+ txt_clip = (
46
+ txt_clip.set_start(start_time)
47
+ .set_end(end_time)
48
+ .set_position(('center', 'bottom'))
49
+ )
50
+ subtitle_clips.append(txt_clip)
51
+ return subtitle_clips
52
+
53
+
54
+ Filepath = str
55
+
56
+
57
+ def process_path(path: Filepath) -> Path:
58
+ return Path(path).expanduser().resolve()
59
+
60
+
61
+ def write_subtitles_in_video(
62
+ video: Filepath, subtitles: Optional[str] = None, output_video: Optional[str] = None
63
+ ):
64
+ """
65
+ Write subtitles in a video.
66
+
67
+ Example usage:
68
+
69
+ >>> output_path = write_subtitles_in_video("~/Downloads/some_video.mp4") # doctest: +SKIP
70
+
71
+ Which is syntactic sugar for the more explicit:
72
+
73
+ >>> output_path = write_subtitles_in_video(
74
+ ... "~/Downloads/some_video.mp4",
75
+ ... subtitles="~/Downloads/Ssome_video.srt",
76
+ ... output_video="~/Downloads/some_video.mp4"
77
+ ... ) # doctest: +SKIP
78
+
79
+ """
80
+ video_path = process_path(video)
81
+
82
+ srt_content, output_video_path = _process_inputs(
83
+ subtitles, output_video, video_path
84
+ )
85
+
86
+ # Load the video file
87
+ video_clip = mp.VideoFileClip(str(video_path))
88
+
89
+ # Generate subtitle clips
90
+ subtitle_clips = generate_subtitle_clips(srt_content, video_clip)
91
+
92
+ # Create a composite video with subtitles
93
+ video_with_subtitles = CompositeVideoClip([video_clip] + subtitle_clips)
94
+
95
+ # Export the video with subtitles
96
+ video_with_subtitles.write_videofile(
97
+ str(output_video_path), codec="libx264", fps=video_clip.fps
98
+ )
99
+
100
+ return output_video_path
101
+
102
+
103
+ def _process_inputs(subtitles, output_video, video_path):
104
+ if subtitles is None:
105
+ subtitles_path = video_path.with_suffix('.srt')
106
+ srt_content = subtitles_path.read_text()
107
+ elif os.path.isfile(subtitles):
108
+ subtitles_path = process_path(subtitles)
109
+ srt_content = subtitles_path.read_text()
110
+ else:
111
+ assert isinstance(subtitles, str), "subtitles should be a string"
112
+ srt_content = subtitles
113
+
114
+ if output_video is None:
115
+ output_video_path = video_path.with_stem(video_path.stem + '_with_subtitles')
116
+ output_video_path = output_video_path.with_suffix(video_path.suffix)
117
+ else:
118
+ output_video_path = Path(output_video)
119
+ return srt_content, output_video_path
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) [year] [fullname]
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.
@@ -0,0 +1,92 @@
1
+ Metadata-Version: 2.1
2
+ Name: mixing
3
+ Version: 0.0.2
4
+ Summary: Tools for video and audio editing
5
+ Home-page: https://github.com/thorwhalen/mixing
6
+ Author: Thor Whalen
7
+ License: mit
8
+ Platform: any
9
+ Description-Content-Type: text/markdown
10
+ License-File: LICENSE
11
+ Requires-Dist: moviepy
12
+
13
+
14
+ # mixing
15
+ Tools for video and audio editing
16
+
17
+
18
+ To install: ```pip install mixing```
19
+
20
+
21
+ # Examples
22
+
23
+ ## mixing.video
24
+
25
+ ### write_subtitles_in_video
26
+
27
+
28
+ Write subtitles in a video.
29
+
30
+ Example usage:
31
+
32
+ ```python
33
+ >>> from mixing import write_subtitles_in_video
34
+ >>> output_path = write_subtitles_in_video("~/Downloads/some_video.mp4")
35
+ ```
36
+
37
+ Which is syntactic sugar for the more explicit:
38
+
39
+ ```python
40
+ >>> output_path = write_subtitles_in_video(
41
+ ... "~/Downloads/some_video.mp4",
42
+ ... subtitles="~/Downloads/some_video.srt",
43
+ ... output_video="~/Downloads/some_video.mp4"
44
+ ... )
45
+ ```
46
+
47
+
48
+ # Further requirements
49
+
50
+ ## FFmpeg
51
+
52
+ Many of the tools also require `ffmeg`.
53
+
54
+ To install FFmpeg on your system, follow the instructions for your operating system below.
55
+
56
+ ### macOS
57
+
58
+ 1. **Using Homebrew:**
59
+ - Open Terminal.
60
+ - Run the following command:
61
+ ```bash
62
+ brew install ffmpeg
63
+ ```
64
+
65
+ For more details, visit the [FFmpeg installation page for macOS](https://ffmpeg.org/download.html#build-mac).
66
+
67
+ ### Linux
68
+
69
+ 1. **Using the package manager:**
70
+ - For Debian/Ubuntu-based distributions, run:
71
+ ```bash
72
+ sudo apt update
73
+ sudo apt install ffmpeg
74
+ ```
75
+ - For Fedora, run:
76
+ ```bash
77
+ sudo dnf install ffmpeg
78
+ ```
79
+ - For Arch Linux, run:
80
+ ```bash
81
+ sudo pacman -S ffmpeg
82
+ ```
83
+
84
+ For more details, visit the [FFmpeg installation page for Linux](https://ffmpeg.org/download.html#build-linux).
85
+
86
+ ### Windows
87
+
88
+ 1. **Using Windows builds:**
89
+ - Download the executable from [FFmpeg for Windows](https://ffmpeg.org/download.html#build-windows).
90
+ - Extract the downloaded files and add the `bin` directory to your system's PATH.
91
+
92
+ For more details, visit the [FFmpeg installation page for Windows](https://ffmpeg.org/download.html#build-windows).
@@ -0,0 +1,7 @@
1
+ mixing/__init__.py,sha256=iXi4Q--wKi1am8kLSR63yX4a3hYgEok-P2VwBBj1fuU,102
2
+ mixing/video/__init__.py,sha256=J_KHLG6YOUsupvx2K1U0BuKP5UCnqiUOoK8SxXhRrQI,3436
3
+ mixing-0.0.2.dist-info/LICENSE,sha256=ACwmltkrXIz5VsEQcrqljq-fat6ZXAMepjXGoe40KtE,1069
4
+ mixing-0.0.2.dist-info/METADATA,sha256=k-xihxGhsnvKfhZ-atpJJjdgT5wGEnB4ItJ-5i9Mrrk,2045
5
+ mixing-0.0.2.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
6
+ mixing-0.0.2.dist-info/top_level.txt,sha256=A-u5KCO6igj85beYBJwz8YHmQLSNCnmC5uaJrUtfzK0,7
7
+ mixing-0.0.2.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: bdist_wheel (0.42.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ mixing