Politrees commited on
Commit
74377b4
·
verified ·
1 Parent(s): 294aebf

Delete steganography.py

Browse files
Files changed (1) hide show
  1. steganography.py +0 -277
steganography.py DELETED
@@ -1,277 +0,0 @@
1
- import logging
2
- import tempfile
3
- import gradio as gr
4
- import librosa
5
- import librosa.display
6
- import matplotlib.pyplot as plt
7
- import numpy as np
8
- import soundfile as sf
9
- from PIL import Image, ImageDraw, ImageFont
10
- import os
11
- import cv2
12
- from moviepy.editor import VideoFileClip, AudioFileClip
13
-
14
- DEFAULT_FONT_PATH = "/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf"
15
- DEFAULT_SAMPLE_RATE = 22050
16
-
17
- logging.basicConfig(level=logging.INFO)
18
-
19
- def load_font(font_path, max_font_size):
20
- try:
21
- return ImageFont.truetype(font_path, max_font_size)
22
- except IOError:
23
- logging.warning(f"Font not found at {font_path}. Using default font.")
24
- return ImageFont.load_default()
25
- except Exception as e:
26
- logging.error(f"An error occurred while loading the font: {e}")
27
- raise
28
-
29
- def create_text_image(text, font, base_width=512, height=256, margin=10, letter_spacing=5):
30
- draw = ImageDraw.Draw(Image.new("L", (1, 1)))
31
- text_widths = [
32
- draw.textbbox((0, 0), char, font=font)[2] - draw.textbbox((0, 0), char, font=font)[0]
33
- for char in text
34
- ]
35
- text_width = sum(text_widths) + letter_spacing * (len(text) - 1)
36
- text_height = (
37
- draw.textbbox((0, 0), text[0], font=font)[3]
38
- - draw.textbbox((0, 0), text[0], font=font)[1]
39
- )
40
-
41
- width = max(base_width, text_width + margin * 2)
42
- height = max(height, text_height + margin * 2)
43
-
44
- image = Image.new("L", (width, height), "black")
45
- draw = ImageDraw.Draw(image)
46
-
47
- text_start_x = (width - text_width) // 2
48
- text_start_y = (height - text_height) // 2
49
-
50
- current_x = text_start_x
51
- for char, char_width in zip(text, text_widths):
52
- draw.text((current_x, text_start_y), char, font=font, fill="white")
53
- current_x += char_width + letter_spacing
54
-
55
- return np.array(image)
56
-
57
- def spectrogram_image_to_audio(image, sr=DEFAULT_SAMPLE_RATE):
58
- flipped_image = np.flipud(image)
59
- S = flipped_image.astype(np.float32) / 255.0 * 100.0
60
- y = librosa.griffinlim(S)
61
- return y
62
-
63
- def create_audio_with_spectrogram(text, base_width, height, max_font_size, margin, letter_spacing):
64
- font = load_font(DEFAULT_FONT_PATH, max_font_size)
65
- spec_image = create_text_image(text, font, base_width, height, margin, letter_spacing)
66
- y = spectrogram_image_to_audio(spec_image)
67
-
68
- with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as temp_audio:
69
- audio_path = temp_audio.name
70
- sf.write(audio_path, y, DEFAULT_SAMPLE_RATE)
71
-
72
- S = librosa.feature.melspectrogram(y=y, sr=DEFAULT_SAMPLE_RATE)
73
- S_dB = librosa.power_to_db(S, ref=np.max)
74
- plt.figure(figsize=(10, 4))
75
- librosa.display.specshow(S_dB, sr=DEFAULT_SAMPLE_RATE, x_axis="time", y_axis="mel")
76
- plt.axis("off")
77
- plt.tight_layout(pad=0)
78
-
79
- with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as temp_spectrogram:
80
- spectrogram_path = temp_spectrogram.name
81
- plt.savefig(spectrogram_path, bbox_inches="tight", pad_inches=0, transparent=True)
82
- plt.close()
83
-
84
- return audio_path, spectrogram_path
85
-
86
- def display_audio_spectrogram(audio_path):
87
- y, sr = librosa.load(audio_path, sr=None)
88
- S = librosa.feature.melspectrogram(y=y, sr=sr)
89
- S_dB = librosa.power_to_db(S, ref=np.max)
90
-
91
- plt.figure(figsize=(10, 4))
92
- librosa.display.specshow(S_dB, sr=sr, x_axis="time", y_axis="mel")
93
- plt.axis("off")
94
- plt.tight_layout(pad=0)
95
-
96
- with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as temp_spectrogram:
97
- spectrogram_path = temp_spectrogram.name
98
- plt.savefig(spectrogram_path, bbox_inches="tight", pad_inches=0, transparent=True)
99
- plt.close()
100
- return spectrogram_path
101
-
102
- def image_to_spectrogram_audio(image_path, sr=DEFAULT_SAMPLE_RATE):
103
- image = Image.open(image_path).convert("L")
104
- image = np.array(image)
105
- y = spectrogram_image_to_audio(image, sr)
106
-
107
- with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as temp_audio:
108
- img2audio_path = temp_audio.name
109
- sf.write(img2audio_path, y, sr)
110
- return img2audio_path
111
-
112
- def gradio_interface_fn(text, base_width, height, max_font_size, margin, letter_spacing):
113
- audio_path, spectrogram_path = create_audio_with_spectrogram(text, base_width, height, max_font_size, margin, letter_spacing)
114
- return audio_path, spectrogram_path
115
-
116
- def gradio_image_to_audio_fn(upload_image):
117
- return image_to_spectrogram_audio(upload_image)
118
-
119
- def gradio_decode_fn(upload_audio):
120
- return display_audio_spectrogram(upload_audio)
121
-
122
- def extract_audio(video_path):
123
- try:
124
- video = VideoFileClip(video_path)
125
- if video.audio is None:
126
- raise ValueError("No audio found in the video")
127
- audio_path = "extracted_audio.wav"
128
- video.audio.write_audiofile(audio_path)
129
- return audio_path
130
- except Exception as e:
131
- logging.error(f"Failed to extract audio: {e}")
132
- return None
133
-
134
- def extract_frames(video_path):
135
- try:
136
- video = cv2.VideoCapture(video_path)
137
- frames = []
138
- success, frame = video.read()
139
- while success:
140
- frames.append(frame)
141
- success, frame = video.read()
142
- video.release()
143
- return frames
144
- except Exception as e:
145
- logging.error(f"Failed to extract frames: {e}")
146
- return None
147
-
148
- def frame_to_spectrogram(frame, sr=DEFAULT_SAMPLE_RATE):
149
- gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
150
- S = np.flipud(gray_frame.astype(np.float32) / 255.0 * 100.0)
151
- y = librosa.griffinlim(S)
152
- return y
153
-
154
- def save_audio(y, sr=DEFAULT_SAMPLE_RATE):
155
- audio_path = 'output_frame_audio.wav'
156
- sf.write(audio_path, y, sr)
157
- return audio_path
158
-
159
- def save_spectrogram_image(S, frame_number, temp_dir):
160
- plt.figure(figsize=(10, 4))
161
- librosa.display.specshow(S)
162
- plt.tight_layout()
163
- image_path = os.path.join(temp_dir, f'spectrogram_frame_{frame_number}.png')
164
- plt.savefig(image_path)
165
- plt.close()
166
- return image_path
167
-
168
- def process_video_frames(frames, sr=DEFAULT_SAMPLE_RATE, temp_dir=None):
169
- processed_frames = []
170
- total_frames = len(frames)
171
- for i, frame in enumerate(frames):
172
- y = frame_to_spectrogram(frame, sr)
173
- S = librosa.feature.melspectrogram(y=y, sr=sr)
174
- image_path = save_spectrogram_image(S, i, temp_dir)
175
- processed_frame = cv2.imread(image_path)
176
- processed_frames.append(processed_frame)
177
- return processed_frames
178
-
179
- def save_video_from_frames(frames, output_path, fps=30):
180
- height, width, layers = frames[0].shape
181
- video = cv2.VideoWriter(output_path, cv2.VideoWriter_fourcc(*'mp4v'), fps, (width, height))
182
- for frame in frames:
183
- video.write(frame)
184
- video.release()
185
-
186
- def add_audio_to_video(video_path, audio_path, output_path):
187
- try:
188
- video = VideoFileClip(video_path)
189
- audio = AudioFileClip(audio_path)
190
- final_video = video.set_audio(audio)
191
- final_video.write_videofile(output_path, codec='libx264', audio_codec='aac')
192
- except Exception as e:
193
- logging.error(f"Failed to add audio to video: {e}")
194
-
195
- def process_video(video_path):
196
- try:
197
- video = VideoFileClip(video_path)
198
- if video.duration > 10:
199
- video = video.subclip(0, 10)
200
- temp_trimmed_video_path = "trimmed_video.mp4"
201
- video.write_videofile(temp_trimmed_video_path, codec='libx264')
202
- video_path = temp_trimmed_video_path
203
- except Exception as e:
204
- return f"Failed to load video: {e}"
205
-
206
- audio_path = extract_audio(video_path)
207
- if audio_path is None:
208
- return "Failed to extract audio from video."
209
- frames = extract_frames(video_path)
210
- if frames is None:
211
- return "Failed to extract frames from video."
212
-
213
- with tempfile.TemporaryDirectory() as temp_dir:
214
- processed_frames = process_video_frames(frames, temp_dir=temp_dir)
215
- temp_video_path = os.path.join(temp_dir, 'processed_video.mp4')
216
- save_video_from_frames(processed_frames, temp_video_path)
217
- output_video_path = 'output_video_with_audio.mp4'
218
- add_audio_to_video(temp_video_path, audio_path, output_video_path)
219
- return output_video_path
220
-
221
- def create_gradio_interface():
222
- with gr.Blocks(title="Audio Steganography", css="footer{display:none !important}", theme=gr.themes.Soft(primary_hue="green", secondary_hue="green", spacing_size="sm", radius_size="lg")) as txt2spec:
223
- with gr.Tab("Text to Spectrogram"):
224
- with gr.Group():
225
- text = gr.Textbox(lines=2, placeholder="Enter your text:", label="Text", info="Enter the text you want to convert to audio.")
226
- with gr.Row(variant="panel"):
227
- base_width = gr.Slider(value=512, label="Image Width", visible=False)
228
- height = gr.Slider(value=256, label="Image Height", visible=False)
229
- max_font_size = gr.Slider(minimum=10, maximum=130, step=5, value=80, label="Font size")
230
- margin = gr.Slider(minimum=0, maximum=50, step=1, value=10, label="Indent")
231
- letter_spacing = gr.Slider(minimum=0, maximum=50, step=1, value=5, label="Letter spacing")
232
- generate_button = gr.Button("Generate", variant="primary", size="lg")
233
-
234
- with gr.Column(variant="panel"):
235
- with gr.Group():
236
- output_audio = gr.Audio(type="filepath", label="Generated audio")
237
- output_spectrogram = gr.Image(type="filepath", label="Spectrogram")
238
-
239
- generate_button.click(gradio_interface_fn, inputs=[text, base_width, height, max_font_size, margin, letter_spacing], outputs=[output_audio, output_spectrogram])
240
-
241
- with gr.Tab("Image to Spectrogram"):
242
- with gr.Group():
243
- with gr.Column():
244
- upload_image = gr.Image(type="filepath", label="Upload image")
245
- convert_button = gr.Button("Convert to audio", variant="primary", size="lg")
246
-
247
- with gr.Column(variant="panel"):
248
- output_audio_from_image = gr.Audio(type="filepath", label="Generated audio")
249
-
250
- convert_button.click(gradio_image_to_audio_fn, inputs=[upload_image], outputs=[output_audio_from_image])
251
-
252
- with gr.Tab("Audio to Spectrogram"):
253
- with gr.Group():
254
- with gr.Column():
255
- upload_audio = gr.Audio(type="filepath", label="Upload audio", scale=3)
256
- decode_button = gr.Button("Show spectrogram", variant="primary", size="lg")
257
-
258
- with gr.Column(variant="panel"):
259
- decoded_image = gr.Image(type="filepath", label="Audio Spectrogram")
260
-
261
- decode_button.click(gradio_decode_fn, inputs=[upload_audio], outputs=[decoded_image])
262
-
263
- with gr.Tab("Video to Spectrogram"):
264
- with gr.Group():
265
- video_input = gr.Video(label="Upload video")
266
- generate_button = gr.Button("Generate", variant="primary", size="lg")
267
-
268
- with gr.Column(variant="panel"):
269
- video_output = gr.Video(label="Video Spectrogram")
270
-
271
- generate_button.click(process_video, inputs=[video_input], outputs=[video_output])
272
-
273
- return txt2spec
274
-
275
- if __name__ == "__main__":
276
- txt2spec = create_gradio_interface()
277
- txt2spec.launch(share=True)