Это необходимо для того, чтобы интервал между каждой речью можно было регулировать в большую или меньшую сторону, а также удаление дубликатов.
Я попытался получить последнюю строку пикселей, проверить значения пикселей и посмотреть, находятся ли их значения RGB или HSV в определенном диапазоне, чтобы считаться реальной речью и тишиной, но я все равно получаю неправильные разделения.

Есть ли лучший способ сделать это ? Конечно, мне все еще нужны несколько дополнительных правил, например, обрезка не должна быть меньше X пикселей, и если тишина в речи меньше Y пикселей, она все равно будет считаться той же речью.
И край существующих сигналов не должен быть разделен, или, если он обнаружен точно, можно разделить его там, потому что тогда ничего не изменится.
В любом случае это мое код, но пока не может правильно сегментировать сигнал. Мне также нужно знать, какие части являются речью, а какие — молчанием, чтобы я мог удалять части молчания по ходу дела. Другая проблема заключается в том, что это длинный звук, и мне приходится прокручивать его, но если звук продолжает выходить за край, это испортит предстоящее разделение для следующей прокрутки.
from colorsys import rgb_to_hsv
import pyautogui
import pygetwindow as gw
import time
import keyboard # For listening to key presses
from PIL import Image, ImageChops, ImageDraw
import os
WINDOW_NAME = "TechSmith Camtasia 2024"
# Define global parameters
start_x = 205
end_x = 3820
y = 2046
region_height = 20 # For debugging visualization
debug_opacity = 25 # 10% opacity (255 * 0.1 = 25)
output_dir = os.path.dirname(os.path.abspath(__file__))
def bring_window_to_foreground(window_name, max_retries=3):
def activate_window(window):
window.activate()
window.minimize()
time.sleep(0.2)
window.maximize()
for attempt in range(max_retries):
windows = gw.getWindowsWithTitle(window_name)
if not windows:
print(f"Attempt {attempt + 1}: Window '{window_name}' not found. Retrying...")
time.sleep(1)
continue
app_window = windows[0]
print(f"Attempt {attempt + 1}: Found window '{window_name}'.")
activate_window(app_window)
print(f"'{window_name}' successfully brought to the foreground.")
return True
print(f"Failed to bring '{window_name}' to the foreground after {max_retries} attempts.")
return False
def check_termination():
if keyboard.is_pressed("esc"):
print("ESC key pressed. Exiting...")
return True
return False
def calculate_contrast_change(image, change_threshold=20):
"""
Calculate significant contrast changes along the X-axis to detect transitions.
Args:
image (PIL.Image): 1-pixel high image for detection.
change_threshold (int): Minimum percentage change to consider significant.
Returns:
splits (list): List of detected split points based on contrast changes.
audio_regions (list): List of (start, end) tuples for identified audio regions.
"""
img_array = image.load()
width = image.width
contrast = [sum(img_array[x, 0]) / 3 for x in range(width)] # Grayscale intensity as the average of RGB
splits = []
audio_regions = []
in_audio = False
audio_start = None
for i in range(1, width):
percent_change = ((contrast - contrast) / contrast) * 100 if contrast > 0 else 0
if percent_change > change_threshold: # Significant increase (audio start)
splits.append(("audio_start", start_x + i))
if not in_audio:
audio_start = start_x + i
in_audio = True
elif percent_change < -change_threshold: # Significant decrease (silence start)
splits.append(("silence_start", start_x + i))
if in_audio:
audio_regions.append((audio_start, start_x + i))
in_audio = False
# If audio continues till the end
if in_audio:
audio_regions.append((audio_start, start_x + width - 1))
return splits, audio_regions
def process_waveform(edit_audio=False, debug_visualization=True, scroll_enabled=False):
deselect_x, deselect_y = 213, 1920
split_key = 's'
click_y_position = 1872
audio_track_y = 2000
last_termination_screenshot = None
screenshot_count = 0
while True:
if check_termination():
break
pyautogui.click(deselect_x, deselect_y)
time.sleep(0.1)
# Take a 1-pixel high screenshot for detection
detection_screenshot = pyautogui.screenshot(region=(start_x, y - 1, end_x - start_x, 1))
# Analyze contrast changes
splits, audio_regions = calculate_contrast_change(detection_screenshot, change_threshold=20)
# Print detected ranges for debugging
for idx, (start, end) in enumerate(audio_regions):
print(f"Range {idx}: {start}-{end} ({end - start})")
if debug_visualization:
# Take a 20-pixel high screenshot for debugging
debug_image = pyautogui.screenshot(region=(start_x, y - region_height, end_x - start_x, region_height))
debug_image = debug_image.convert("RGB")
overlay = Image.new("RGBA", debug_image.size, (0, 0, 0, 0)) # Transparent overlay
draw = ImageDraw.Draw(overlay, "RGBA")
# Draw splits
for label, position in splits:
color = "red" if label == "audio_start" else "blue"
draw.line([(position - start_x, 0), (position - start_x, region_height)], fill=color, width=1)
# Overlay green on audio regions
for start, end in audio_regions:
draw.rectangle(
[(start - start_x, 0), (end - start_x, region_height)],
fill=(0, 255, 0, debug_opacity),
)
# Composite overlay with original debug image
debug_image = Image.alpha_composite(debug_image.convert("RGBA"), overlay)
debug_path = os.path.join(output_dir, f"debug_{screenshot_count}.png")
debug_image.save(debug_path)
print(f"Saved debug visualization: {debug_path}")
screenshot_count += 1
# Scroll disabled for debugging, exit after processing current screen
if not scroll_enabled:
print("Scroll disabled. Debugging mode exiting after one iteration.")
break
def main():
if bring_window_to_foreground(WINDOW_NAME):
time.sleep(1)
print("Camtasia is active. Starting waveform processing...")
process_waveform(edit_audio=False, debug_visualization=True, scroll_enabled=False)
else:
print("Exiting script. Unable to activate Camtasia.")
if __name__ == "__main__":
main()
Подробнее здесь: https://stackoverflow.com/questions/792 ... o-waveform