ppt2video 0.1.0__tar.gz

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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Andy Kim
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,86 @@
1
+ Metadata-Version: 2.1
2
+ Name: ppt2video
3
+ Version: 0.1.0
4
+ Summary: A tool that converts a PowerPoint (PPT) to a video with voice narration (reading the notes from each slide)
5
+ Home-page: https://github.com/iburn78/ppt2video
6
+ Author: IssueTracker
7
+ Author-email: issuetree.tracker@gmail.com
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.6
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: python-pptx
15
+ Requires-Dist: moviepy
16
+ Requires-Dist: google-cloud-texttospeech
17
+
18
+ # ppt2video
19
+ ## A tool that converts a PowerPoint (PPT) to a video with voice narration (reading the notes from each slide)
20
+
21
+ This tool reads the note contents from each slide using Google TTS and converts the PPT to an MP4 video.
22
+
23
+ ### Installation
24
+
25
+ ```
26
+ pip install ppt2video
27
+ ```
28
+
29
+
30
+ ### Usage
31
+
32
+ + Step 1: Place your PPT file (or `.pptx`) into a specific folder (e.g., `data/ppt/your_ppt_name.pptx`).
33
+
34
+ + Step 2: Open your PowerPoint software and save the slides as images (e.g., PNG) to a specific folder (usually, `data/ppt/your_ppt_name/`).
35
+
36
+ + Step 3: Set up Google Cloud Authentication to access the note contents in your slides:
37
+
38
+ - You need to set up authentication using your Google Cloud service account key. Follow these steps:
39
+ * Go to the Google Cloud Console ([https://console.cloud.google.com/](https://console.cloud.google.com/)).
40
+ * Create a new project (or use an existing project).
41
+ * Enable the Text-to-Speech API for that project.
42
+ * Create a Service Account and download the JSON key file.
43
+
44
+ + Step 4: Run the code
45
+
46
+ ```python
47
+ from ppt2video.tools import *
48
+
49
+ meta = Meta(
50
+ ppt_file='your_ppt_slide.pptx', # Name of your PPT file
51
+ image_prefix='slide', # The prefix for image files (varies depending on the PowerPoint language version)
52
+ google_application_credentials='/config/google_cloud.json' # Location and filename of your Google Cloud service account key
53
+ )
54
+
55
+ # Run the conversion
56
+ ppt_to_video(meta)
57
+ ```
58
+
59
+ ### Additional settings
60
+ You may adjust additional settings as follows:
61
+
62
+ ```python
63
+ # PPT settings
64
+ ppt_file: str
65
+ ppt_path: str = 'data/ppt/' # Directory for the PPT and image files
66
+ image_prefix: str = 'slide' # The prefix for image file names (used when saving slides as images)
67
+ image_extension: str = 'PNG' # The image file format (default is PNG)
68
+ ppt_extension: str = '.pptx' # The PowerPoint file extension
69
+
70
+ # Google TTS settings
71
+ voice_enabled: bool = True # Enable or disable voice narration
72
+ google_application_credentials: str = None # Location of the Google API key (downloaded as JSON)
73
+ voice_path: str = 'data/voice/' # Directory to save the generated audio files
74
+ max_size: int = 4500 # Maximum text size limit for a single Google TTS API request (default 5000)
75
+ slide_break: float = 2 # Time delay (in seconds) between slides
76
+ line_break: float = 0.7 # Time delay (in seconds) when there's a line break in the text (e.g., '\n')
77
+ lang: str = 'E' # Language setting: 'E' for English, 'K' for Korean
78
+ wave: bool = False # Whether to use Wavenet voices (True or False)
79
+
80
+ # MoviePy video settings
81
+ fps: int = 24 # Frames per second for the video
82
+ ```
83
+
84
+
85
+
86
+
@@ -0,0 +1,69 @@
1
+ # ppt2video
2
+ ## A tool that converts a PowerPoint (PPT) to a video with voice narration (reading the notes from each slide)
3
+
4
+ This tool reads the note contents from each slide using Google TTS and converts the PPT to an MP4 video.
5
+
6
+ ### Installation
7
+
8
+ ```
9
+ pip install ppt2video
10
+ ```
11
+
12
+
13
+ ### Usage
14
+
15
+ + Step 1: Place your PPT file (or `.pptx`) into a specific folder (e.g., `data/ppt/your_ppt_name.pptx`).
16
+
17
+ + Step 2: Open your PowerPoint software and save the slides as images (e.g., PNG) to a specific folder (usually, `data/ppt/your_ppt_name/`).
18
+
19
+ + Step 3: Set up Google Cloud Authentication to access the note contents in your slides:
20
+
21
+ - You need to set up authentication using your Google Cloud service account key. Follow these steps:
22
+ * Go to the Google Cloud Console ([https://console.cloud.google.com/](https://console.cloud.google.com/)).
23
+ * Create a new project (or use an existing project).
24
+ * Enable the Text-to-Speech API for that project.
25
+ * Create a Service Account and download the JSON key file.
26
+
27
+ + Step 4: Run the code
28
+
29
+ ```python
30
+ from ppt2video.tools import *
31
+
32
+ meta = Meta(
33
+ ppt_file='your_ppt_slide.pptx', # Name of your PPT file
34
+ image_prefix='slide', # The prefix for image files (varies depending on the PowerPoint language version)
35
+ google_application_credentials='/config/google_cloud.json' # Location and filename of your Google Cloud service account key
36
+ )
37
+
38
+ # Run the conversion
39
+ ppt_to_video(meta)
40
+ ```
41
+
42
+ ### Additional settings
43
+ You may adjust additional settings as follows:
44
+
45
+ ```python
46
+ # PPT settings
47
+ ppt_file: str
48
+ ppt_path: str = 'data/ppt/' # Directory for the PPT and image files
49
+ image_prefix: str = 'slide' # The prefix for image file names (used when saving slides as images)
50
+ image_extension: str = 'PNG' # The image file format (default is PNG)
51
+ ppt_extension: str = '.pptx' # The PowerPoint file extension
52
+
53
+ # Google TTS settings
54
+ voice_enabled: bool = True # Enable or disable voice narration
55
+ google_application_credentials: str = None # Location of the Google API key (downloaded as JSON)
56
+ voice_path: str = 'data/voice/' # Directory to save the generated audio files
57
+ max_size: int = 4500 # Maximum text size limit for a single Google TTS API request (default 5000)
58
+ slide_break: float = 2 # Time delay (in seconds) between slides
59
+ line_break: float = 0.7 # Time delay (in seconds) when there's a line break in the text (e.g., '\n')
60
+ lang: str = 'E' # Language setting: 'E' for English, 'K' for Korean
61
+ wave: bool = False # Whether to use Wavenet voices (True or False)
62
+
63
+ # MoviePy video settings
64
+ fps: int = 24 # Frames per second for the video
65
+ ```
66
+
67
+
68
+
69
+
File without changes
@@ -0,0 +1,208 @@
1
+ from dataclasses import dataclass
2
+ from pptx import Presentation
3
+ from google.cloud import texttospeech_v1beta1 as tts
4
+ from moviepy.editor import ImageClip, concatenate_videoclips, AudioFileClip
5
+ import os
6
+
7
+ @dataclass
8
+ class Meta:
9
+ # PPT settings
10
+ ppt_file: str
11
+ ppt_path: str = 'data/ppt/' # Directory for the PPT and image files
12
+ image_prefix: str = 'slide' # The prefix for image file names (used when saving slides as images)
13
+ image_extension: str = 'PNG' # The image file format (default is PNG)
14
+ ppt_extension: str = '.pptx' # The PowerPoint file extension
15
+
16
+ # Google TTS settings
17
+ voice_enabled: bool = True # Enable or disable voice narration
18
+ google_application_credentials: str = None # Location of the Google API key (downloaded as JSON)
19
+ voice_path: str = 'data/voice/' # Directory to save the generated audio files
20
+ max_size: int = 4500 # Maximum text size limit for a single Google TTS API request (default 5000)
21
+ slide_break: float = 2 # Time delay (in seconds) between slides
22
+ line_break: float = 0.7 # Time delay (in seconds) when there's a line break in the text (e.g., '\n')
23
+ lang: str = 'E' # Language setting: 'E' for English, 'K' for Korean
24
+ wave: bool = False # Whether to use Wavenet voices (True or False)
25
+
26
+ # MoviePy video settings
27
+ fps: int = 24 # Frames per second for the video
28
+
29
+
30
+ def ppt_to_video(meta: Meta):
31
+ if not os.path.exists(meta.ppt_path):
32
+ os.makedirs(meta.ppt_path)
33
+
34
+ if meta.voice_enabled:
35
+ if meta.google_application_credentials == None:
36
+ print('*****')
37
+ print('Need to set up Google Cloud Authentication')
38
+ print('Please refer to the README.md')
39
+ print('*****')
40
+ return None
41
+
42
+ if not os.path.exists(meta.voice_path):
43
+ os.makedirs(meta.voice_path)
44
+ num = ppt_to_text(meta)
45
+ timepoints = ppt_tts(meta, num)
46
+ video_from_ppt_and_voice(meta, timepoints)
47
+ else:
48
+ num = ppt_to_text(meta)
49
+ video_from_ppt(meta, num)
50
+
51
+ def ppt_to_text(meta: Meta):
52
+ ppt = Presentation(os.path.join(meta.ppt_path, meta.ppt_file))
53
+ if not meta.voice_enabled:
54
+ return len(ppt.slides)
55
+
56
+ def _write_to_file(content, current_file_number, current_size, meta: Meta):
57
+ txt_file = f"{os.path.join(meta.voice_path, meta.ppt_file.replace(meta.ppt_extension, ''))}_{current_file_number}.txt"
58
+
59
+ mode = 'w' if current_size == 0 else 'a'
60
+ with open(txt_file, mode, encoding='utf-8') as notes_file:
61
+ notes_file.write(content)
62
+
63
+ return current_size + len(content.encode('utf-8'))
64
+
65
+ header = '''<speak>
66
+ '''
67
+ footer = '''</speak>
68
+ '''
69
+ file_number = 0
70
+ current_size = _write_to_file(header, file_number, 0, meta)
71
+
72
+ for slide_number, slide in enumerate(ppt.slides):
73
+ if slide.notes_slide and slide.notes_slide.notes_text_frame:
74
+ notes = slide.notes_slide.notes_text_frame.text
75
+ slide_content = f'.<mark name="slide{slide_number}"/>.\n<break time="{round(meta.slide_break/2,1)}s"/>\n'
76
+ slide_content += notes.replace('\n', f'<break time="{meta.line_break}s"/>\n') + f'<break time="{meta.slide_break}s"/>\n'
77
+ else:
78
+ slide_content = f'.<mark name="slide{slide_number}"/>.\n<break time="{meta.slide_break}s"/>\n'
79
+
80
+ if current_size + len(slide_content.encode('utf-8')) > meta.max_size:
81
+ _write_to_file(footer, file_number, current_size, meta)
82
+ file_number += 1
83
+ current_size = 0
84
+ slide_content = header + slide_content
85
+
86
+ current_size = _write_to_file(slide_content, file_number, current_size, meta)
87
+
88
+ _write_to_file(footer, file_number, current_size, meta)
89
+ txt_file_number = file_number+1
90
+
91
+ return txt_file_number
92
+
93
+
94
+ def ppt_tts(meta: Meta, txt_file_number: int):
95
+
96
+ os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = meta.google_application_credentials
97
+
98
+ client = tts.TextToSpeechClient()
99
+ language_code = 'ko-KR' if meta.lang == 'K' else 'en-US'
100
+ tag = 'D' if meta.lang == 'K' else 'B'
101
+ name = language_code+'-Wavenet-'+tag
102
+ if meta.wave == True: # WaveNet voice (1 mil words/month vs 4 mil in basic)
103
+ voice = tts.VoiceSelectionParams(language_code=language_code, name=name, ssml_gender=tts.SsmlVoiceGender.MALE)
104
+ else:
105
+ voice = tts.VoiceSelectionParams(language_code=language_code, ssml_gender=tts.SsmlVoiceGender.MALE)
106
+ audio_config = tts.AudioConfig(audio_encoding=tts.AudioEncoding.MP3)
107
+
108
+ timepoint_dict = {}
109
+ for i in range(txt_file_number):
110
+ txt_file = f"{os.path.join(meta.voice_path, meta.ppt_file.replace(meta.ppt_extension, '_'+str(i)+'.txt'))}"
111
+ voice_file =os.path.join(meta.voice_path, meta.ppt_file.replace(meta.ppt_extension, '_'+str(i)+'.mp3'))
112
+
113
+ with open(txt_file, 'r', encoding='utf-8') as file:
114
+ text_content = file.read()
115
+
116
+ synthesis_input = tts.SynthesisInput(ssml=text_content)
117
+ request = tts.SynthesizeSpeechRequest(
118
+ input=synthesis_input,
119
+ voice=voice,
120
+ audio_config=audio_config,
121
+ enable_time_pointing=[tts.SynthesizeSpeechRequest.TimepointType.SSML_MARK]
122
+ )
123
+ response = client.synthesize_speech(request=request)
124
+
125
+ with open(voice_file, "wb") as out:
126
+ out.write(response.audio_content)
127
+ print(voice_file + ' done')
128
+
129
+ timepoint_list = []
130
+ if response.timepoints:
131
+ for time_point in response.timepoints:
132
+ print(f'Mark name: {time_point.mark_name}, Time: {time_point.time_seconds} seconds')
133
+ timepoint_list.append([int(time_point.mark_name[5:]), time_point.time_seconds])
134
+ else:
135
+ print('No timepoints found.')
136
+ timepoint_dict[voice_file] = timepoint_list
137
+
138
+ return timepoint_dict
139
+
140
+ def video_from_ppt_and_voice(meta: Meta, timepoints, fps=24):
141
+ images_path = os.path.join(meta.ppt_path, meta.ppt_file.replace(meta.ppt_extension,''))
142
+ output_file = os.path.join(meta.ppt_path, meta.ppt_file.replace(meta.ppt_extension, '.mp4'))
143
+ video_with_audios = []
144
+
145
+ for audio_file, slide_times in timepoints.items():
146
+ audio_clip = AudioFileClip(audio_file)
147
+
148
+ video_clips = []
149
+ for i in range(len(slide_times)):
150
+ start_time = slide_times[i][1] # Get the start time for the slide
151
+ if i < len(slide_times)-1:
152
+ end_time = slide_times[i + 1][1] # Get the end time for the next slide
153
+ else:
154
+ end_time = audio_clip.duration
155
+ slide_number = slide_times[i][0]
156
+
157
+ # Construct the image filename
158
+ slide_image_filename = f'{meta.image_prefix}{slide_number}.PNG'
159
+ slide_image_path = os.path.join(images_path, slide_image_filename)
160
+
161
+ # Load the slide image
162
+ slide_clip = ImageClip(slide_image_path).set_duration(end_time - start_time).set_start(start_time)
163
+ video_clips.append(slide_clip)
164
+
165
+ # Concatenate video clips for the current audio
166
+ video_with_audio = concatenate_videoclips(video_clips)
167
+ video_with_audio = video_with_audio.set_audio(audio_clip).volumex(2)
168
+ video_with_audios.append(video_with_audio)
169
+
170
+ # Concatenate all videos into one final video
171
+ final_video = concatenate_videoclips(video_with_audios)
172
+
173
+ # Set fps for the final video
174
+ final_video.fps = fps
175
+
176
+ # final_video.write_videofile(output_file, codec="libx264")
177
+ final_video.write_videofile(
178
+ output_file,
179
+ codec="libx264",
180
+ )
181
+ print('video with audio generated and saved')
182
+
183
+ def video_from_ppt(meta: Meta, num_slides: int, fps=24):
184
+ images_path = os.path.join(meta.ppt_path, meta.ppt_file.replace(meta.ppt_extension,''))
185
+ output_file = os.path.join(meta.ppt_path, meta.ppt_file.replace(meta.ppt_extension, '.mp4'))
186
+
187
+ video_clips = []
188
+ for i in range(num_slides):
189
+ start_time = i*meta.slide_break
190
+ end_time = start_time+meta.slide_break
191
+
192
+ slide_image_filename = f'{meta.image_prefix}{i}.{meta.image_extension}'
193
+ slide_image_path = os.path.join(images_path, slide_image_filename)
194
+
195
+ slide_clip = ImageClip(slide_image_path).set_duration(end_time - start_time).set_start(start_time)
196
+ video_clips.append(slide_clip)
197
+
198
+ final_video = concatenate_videoclips(video_clips)
199
+
200
+ # Set fps for the final video
201
+ final_video.fps = fps
202
+
203
+ # final_video.write_videofile(output_file, codec="libx264")
204
+ final_video.write_videofile(
205
+ output_file,
206
+ codec="libx264",
207
+ )
208
+ print('video generated and saved')
@@ -0,0 +1,86 @@
1
+ Metadata-Version: 2.1
2
+ Name: ppt2video
3
+ Version: 0.1.0
4
+ Summary: A tool that converts a PowerPoint (PPT) to a video with voice narration (reading the notes from each slide)
5
+ Home-page: https://github.com/iburn78/ppt2video
6
+ Author: IssueTracker
7
+ Author-email: issuetree.tracker@gmail.com
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.6
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: python-pptx
15
+ Requires-Dist: moviepy
16
+ Requires-Dist: google-cloud-texttospeech
17
+
18
+ # ppt2video
19
+ ## A tool that converts a PowerPoint (PPT) to a video with voice narration (reading the notes from each slide)
20
+
21
+ This tool reads the note contents from each slide using Google TTS and converts the PPT to an MP4 video.
22
+
23
+ ### Installation
24
+
25
+ ```
26
+ pip install ppt2video
27
+ ```
28
+
29
+
30
+ ### Usage
31
+
32
+ + Step 1: Place your PPT file (or `.pptx`) into a specific folder (e.g., `data/ppt/your_ppt_name.pptx`).
33
+
34
+ + Step 2: Open your PowerPoint software and save the slides as images (e.g., PNG) to a specific folder (usually, `data/ppt/your_ppt_name/`).
35
+
36
+ + Step 3: Set up Google Cloud Authentication to access the note contents in your slides:
37
+
38
+ - You need to set up authentication using your Google Cloud service account key. Follow these steps:
39
+ * Go to the Google Cloud Console ([https://console.cloud.google.com/](https://console.cloud.google.com/)).
40
+ * Create a new project (or use an existing project).
41
+ * Enable the Text-to-Speech API for that project.
42
+ * Create a Service Account and download the JSON key file.
43
+
44
+ + Step 4: Run the code
45
+
46
+ ```python
47
+ from ppt2video.tools import *
48
+
49
+ meta = Meta(
50
+ ppt_file='your_ppt_slide.pptx', # Name of your PPT file
51
+ image_prefix='slide', # The prefix for image files (varies depending on the PowerPoint language version)
52
+ google_application_credentials='/config/google_cloud.json' # Location and filename of your Google Cloud service account key
53
+ )
54
+
55
+ # Run the conversion
56
+ ppt_to_video(meta)
57
+ ```
58
+
59
+ ### Additional settings
60
+ You may adjust additional settings as follows:
61
+
62
+ ```python
63
+ # PPT settings
64
+ ppt_file: str
65
+ ppt_path: str = 'data/ppt/' # Directory for the PPT and image files
66
+ image_prefix: str = 'slide' # The prefix for image file names (used when saving slides as images)
67
+ image_extension: str = 'PNG' # The image file format (default is PNG)
68
+ ppt_extension: str = '.pptx' # The PowerPoint file extension
69
+
70
+ # Google TTS settings
71
+ voice_enabled: bool = True # Enable or disable voice narration
72
+ google_application_credentials: str = None # Location of the Google API key (downloaded as JSON)
73
+ voice_path: str = 'data/voice/' # Directory to save the generated audio files
74
+ max_size: int = 4500 # Maximum text size limit for a single Google TTS API request (default 5000)
75
+ slide_break: float = 2 # Time delay (in seconds) between slides
76
+ line_break: float = 0.7 # Time delay (in seconds) when there's a line break in the text (e.g., '\n')
77
+ lang: str = 'E' # Language setting: 'E' for English, 'K' for Korean
78
+ wave: bool = False # Whether to use Wavenet voices (True or False)
79
+
80
+ # MoviePy video settings
81
+ fps: int = 24 # Frames per second for the video
82
+ ```
83
+
84
+
85
+
86
+
@@ -0,0 +1,10 @@
1
+ LICENSE
2
+ README.md
3
+ setup.py
4
+ ppt2video/__init__.py
5
+ ppt2video/tools.py
6
+ ppt2video.egg-info/PKG-INFO
7
+ ppt2video.egg-info/SOURCES.txt
8
+ ppt2video.egg-info/dependency_links.txt
9
+ ppt2video.egg-info/requires.txt
10
+ ppt2video.egg-info/top_level.txt
@@ -0,0 +1,3 @@
1
+ python-pptx
2
+ moviepy
3
+ google-cloud-texttospeech
@@ -0,0 +1 @@
1
+ ppt2video
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,26 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ setup(
4
+ name='ppt2video', # Name of the package
5
+ version='0.1.0', # Version number
6
+ packages=find_packages(), # Automatically finds all packages in the directory
7
+ install_requires=[ # List dependencies here
8
+ 'python-pptx',
9
+ 'moviepy',
10
+ 'google-cloud-texttospeech'
11
+ ],
12
+ entry_points={ # If your package has entry points (CLI tools)
13
+ },
14
+ author='IssueTracker',
15
+ author_email='issuetree.tracker@gmail.com',
16
+ description='A tool that converts a PowerPoint (PPT) to a video with voice narration (reading the notes from each slide)',
17
+ long_description=open('README.md').read(), # Detailed description (usually from README)
18
+ long_description_content_type='text/markdown', # Format of README
19
+ url='https://github.com/iburn78/ppt2video', # URL for your package (GitHub link, etc.)
20
+ classifiers=[ # Optional metadata classifiers
21
+ 'Programming Language :: Python :: 3',
22
+ 'License :: OSI Approved :: MIT License',
23
+ 'Operating System :: OS Independent',
24
+ ],
25
+ python_requires='>=3.6', # Python version requirement
26
+ )