Add audio, scripts, and captcha generation tools
Added new media files (video, audio, subtitles), two scripts for audio combination and captcha audio generation, and updated main.py and server.py for voice and speed settings. Script files were revised for clarity and additional instructions, supporting new workflow for proctor scheduling system documentation and audio generation.
This commit is contained in:
BIN
FPS Signup - How to sign up to an assessment.mkv
Normal file
BIN
FPS Signup - How to sign up to an assessment.mkv
Normal file
Binary file not shown.
BIN
Test_Output.wav
Normal file
BIN
Test_Output.wav
Normal file
Binary file not shown.
64
combine_audio.py
Normal file
64
combine_audio.py
Normal file
@@ -0,0 +1,64 @@
|
||||
import sys
|
||||
import os
|
||||
import wave
|
||||
|
||||
# Usage:
|
||||
# python combine_wavs.py "abc123" "output.wav"
|
||||
|
||||
if len(sys.argv) < 3:
|
||||
print('Usage: python combine_wavs.py "text" "output.wav"')
|
||||
sys.exit(1)
|
||||
|
||||
text = sys.argv[1].lower()
|
||||
output_filename = sys.argv[2]
|
||||
|
||||
current_folder = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
# Folder where a.wav, b.wav, c.wav, 0.wav, 1.wav, etc. are stored
|
||||
base_folder = os.path.join(current_folder, "captcha_audio")
|
||||
print(f"Using base folder: {base_folder}")
|
||||
|
||||
# Output folder
|
||||
output_folder = os.path.join(current_folder)
|
||||
os.makedirs(output_folder, exist_ok=True)
|
||||
|
||||
output_path = os.path.join(output_folder, output_filename)
|
||||
|
||||
# Build the ordered list of WAVs to merge
|
||||
wav_paths = []
|
||||
|
||||
for ch in text:
|
||||
if ch.isspace():
|
||||
continue # ignore spaces
|
||||
|
||||
key = ch.lower() # your files are a.wav, b.wav, ...
|
||||
wav_name = f"{key}.wav"
|
||||
wav_path = os.path.join(base_folder, wav_name)
|
||||
|
||||
if not os.path.exists(wav_path):
|
||||
raise FileNotFoundError(f"Missing WAV for character: {ch} ({wav_path})")
|
||||
|
||||
wav_paths.append(wav_path)
|
||||
|
||||
if not wav_paths:
|
||||
raise ValueError("No valid characters found to assemble.")
|
||||
|
||||
|
||||
# Concatenate WAV files
|
||||
with wave.open(wav_paths[0], "rb") as w:
|
||||
params = w.getparams()
|
||||
combined_frames = [w.readframes(w.getnframes())]
|
||||
|
||||
for wav_file in wav_paths[1:]:
|
||||
with wave.open(wav_file, "rb") as w:
|
||||
if w.getparams() != params:
|
||||
raise ValueError(f"WAV format mismatch: {wav_file}")
|
||||
combined_frames.append(w.readframes(w.getnframes()))
|
||||
|
||||
# Write output
|
||||
with wave.open(output_path, "wb") as out:
|
||||
out.setparams(params)
|
||||
for frames in combined_frames:
|
||||
out.writeframes(frames)
|
||||
|
||||
print(f"Saved combined WAV: {output_path}")
|
||||
2
main.py
2
main.py
@@ -501,7 +501,7 @@ content = ' '.join(content.splitlines())
|
||||
# Option 1: Let the model handle its own splitting by not providing a split pattern:
|
||||
generator = pipeline(
|
||||
content, voice='af_heart', # Change voice if desired
|
||||
speed=0.85
|
||||
speed=0.8
|
||||
)
|
||||
|
||||
# Option 2: Alternatively, use a regex that splits on sentence boundaries (uncomment to use):
|
||||
|
||||
609
make_captcha_audio.py
Normal file
609
make_captcha_audio.py
Normal file
@@ -0,0 +1,609 @@
|
||||
# from kokoro import KPipeline
|
||||
# from IPython.display import display, Audio
|
||||
# import soundfile as sf
|
||||
# import os
|
||||
# import sys
|
||||
# from pydub import AudioSegment
|
||||
|
||||
# # need to install pytorch https://pytorch.org/get-started/locally/
|
||||
|
||||
# script_directory = os.path.dirname(os.path.abspath(sys.argv[0]))
|
||||
|
||||
# pipeline = KPipeline(lang_code='a')
|
||||
# content = ''
|
||||
# print('please input path')
|
||||
# file_path = input()
|
||||
|
||||
# with open(file_path, 'r') as file:
|
||||
# content = file.read()
|
||||
# print(content)
|
||||
|
||||
|
||||
# generator = pipeline(
|
||||
# content, voice='af_bella', # <= change voice here
|
||||
# speed=1, split_pattern=r'\n+'
|
||||
# )
|
||||
|
||||
# count = 0
|
||||
|
||||
# for i, (gs, ps, audio) in enumerate(generator):
|
||||
# print(i) # i => index
|
||||
# print(gs) # gs => graphemes/text
|
||||
# print(ps) # ps => phonemes
|
||||
# display(Audio(data=audio, rate=24000, autoplay=i==0))
|
||||
# sf.write(f'{i}.wav', audio, 24000) # save each audio file
|
||||
# count = count + 1
|
||||
|
||||
# directory = script_directory
|
||||
|
||||
# # Merge WAV files from 0.wav to 334.wav
|
||||
# combined = AudioSegment.empty()
|
||||
|
||||
# for i in range(count): # 0 to 334 inclusive
|
||||
# file_path = f"{directory}/{i}.wav"
|
||||
# sound = AudioSegment.from_wav(file_path)
|
||||
# combined += sound
|
||||
|
||||
# # Export the merged WAV file
|
||||
# output_path = f"{directory}/message.wav"
|
||||
# combined.export(output_path, format="wav")
|
||||
|
||||
# print(f"Merged WAV file saved as {output_path}")
|
||||
# import os
|
||||
# import sys
|
||||
# from kokoro import KPipeline
|
||||
# from IPython.display import display, Audio
|
||||
# import soundfile as sf
|
||||
# from pydub import AudioSegment
|
||||
# import torch
|
||||
|
||||
# # Libraries for PDF and EPUB extraction
|
||||
# import PyPDF2
|
||||
# from ebooklib import epub
|
||||
# from bs4 import BeautifulSoup
|
||||
|
||||
# # Get the directory of the current script
|
||||
# script_directory = os.path.dirname(os.path.abspath(sys.argv[0]))
|
||||
# device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
||||
# # Initialize the pipeline (ensure you have installed and set up kokoro correctly)
|
||||
# pipeline = KPipeline(lang_code='a')
|
||||
# pipeline.model.to(device)
|
||||
# # Ask the user for the file path
|
||||
# print('Please input the file path (txt, pdf, or epub):')
|
||||
# file_path = input().strip()
|
||||
|
||||
# # Determine the file extension
|
||||
# file_ext = os.path.splitext(file_path)[1].lower()
|
||||
# content = ''
|
||||
|
||||
# if file_ext == '.txt':
|
||||
# # For plain text files, just read the content
|
||||
# with open(file_path, 'r', encoding='utf-8') as file:
|
||||
# content = file.read()
|
||||
# elif file_ext == '.pdf':
|
||||
# # For PDFs, open the file in binary mode and extract text from each page
|
||||
# with open(file_path, 'rb') as file:
|
||||
# reader = PyPDF2.PdfReader(file)
|
||||
# for page in reader.pages:
|
||||
# text = page.extract_text()
|
||||
# if text:
|
||||
# content += text + '\n'
|
||||
# elif file_ext == '.epub':
|
||||
# # For EPUBs, use ebooklib to read the book and BeautifulSoup to extract text
|
||||
# book = epub.read_epub(file_path)
|
||||
# for item in book.get_items():
|
||||
# if item.get_type() == epub.ITEM_DOCUMENT:
|
||||
# soup = BeautifulSoup(item.get_content(), 'html.parser')
|
||||
# text = soup.get_text()
|
||||
# content += text + '\n'
|
||||
# else:
|
||||
# print("Unsupported file format. Please provide a .txt, .pdf, or .epub file.")
|
||||
# sys.exit(1)
|
||||
|
||||
# # Display the extracted content (optional)
|
||||
# print(content)
|
||||
|
||||
# # Use the pipeline to generate speech from the text content
|
||||
# generator = pipeline(
|
||||
# content, voice='af_bella', # Change the voice here if desired
|
||||
# speed=1, split_pattern=r'\n+'
|
||||
# )
|
||||
|
||||
# count = 0
|
||||
# for i, (gs, ps, audio) in enumerate(generator):
|
||||
# print(i) # index of the segment
|
||||
# print(gs) # graphemes/text for this segment
|
||||
# print(ps) # phonemes for this segment
|
||||
# display(Audio(data=audio, rate=24000, autoplay=i==0))
|
||||
# sf.write(f'{i}.wav', audio, 24000) # Save each audio file
|
||||
# count += 1
|
||||
|
||||
# # Merge all individual WAV files into one
|
||||
# combined = AudioSegment.empty()
|
||||
# for i in range(count):
|
||||
# wav_path = os.path.join(script_directory, f"{i}.wav")
|
||||
# sound = AudioSegment.from_wav(wav_path)
|
||||
# combined += sound
|
||||
|
||||
# # Export the merged WAV file
|
||||
# output_path = os.path.join(script_directory, "output.wav")
|
||||
# combined.export(output_path, format="wav")
|
||||
# print(f"Merged WAV file saved as {output_path}")
|
||||
|
||||
# # Cleanup: Remove individual part files after merging
|
||||
# for i in range(count):
|
||||
# part_file = os.path.join(script_directory, f"{i}.wav")
|
||||
# if os.path.exists(part_file):
|
||||
# os.remove(part_file)
|
||||
# print(f"Removed {part_file}")
|
||||
|
||||
# import os
|
||||
# import sys
|
||||
# from kokoro import KPipeline
|
||||
# from IPython.display import display, Audio
|
||||
# import soundfile as sf
|
||||
# from pydub import AudioSegment
|
||||
|
||||
# # Libraries for PDF and EPUB extraction
|
||||
# import PyPDF2
|
||||
# from ebooklib import epub
|
||||
# from bs4 import BeautifulSoup
|
||||
|
||||
# # Get the directory of the current script
|
||||
# script_directory = os.path.dirname(os.path.abspath(sys.argv[0]))
|
||||
|
||||
# # Initialize the pipeline (ensure you have installed and set up kokoro correctly)
|
||||
# pipeline = KPipeline(lang_code='a')
|
||||
|
||||
# # Ask the user for the file path
|
||||
# print('Please input the file path (txt, pdf, or epub):')
|
||||
# file_path = input().strip()
|
||||
|
||||
# # Determine the file extension and prepare content
|
||||
# file_ext = os.path.splitext(file_path)[1].lower()
|
||||
# content = ''
|
||||
|
||||
# if file_ext == '.txt':
|
||||
# with open(file_path, 'r', encoding='utf-8') as file:
|
||||
# content = file.read()
|
||||
# elif file_ext == '.pdf':
|
||||
# with open(file_path, 'rb') as file:
|
||||
# reader = PyPDF2.PdfReader(file)
|
||||
# for page in reader.pages:
|
||||
# text = page.extract_text()
|
||||
# if text:
|
||||
# content += text + '\n'
|
||||
# elif file_ext == '.epub':
|
||||
# book = epub.read_epub(file_path)
|
||||
# for item in book.get_items():
|
||||
# if item.get_type() == epub.ITEM_DOCUMENT:
|
||||
# soup = BeautifulSoup(item.get_content(), 'html.parser')
|
||||
# text = soup.get_text()
|
||||
# content += text + '\n'
|
||||
# else:
|
||||
# print("Unsupported file format. Please provide a .txt, .pdf, or .epub file.")
|
||||
# sys.exit(1)
|
||||
|
||||
# # Optionally display the extracted content
|
||||
# print(content)
|
||||
|
||||
# # Generate the audio segments using the pipeline
|
||||
# generator = pipeline(
|
||||
# content, voice='af_bella', # Change voice if desired
|
||||
# speed=1, split_pattern=r'\n+'
|
||||
# )
|
||||
|
||||
# count = 0
|
||||
# for i, (gs, ps, audio) in enumerate(generator):
|
||||
# print(i) # index of the segment
|
||||
# print(gs) # graphemes/text for this segment
|
||||
# print(ps) # phonemes for this segment
|
||||
# display(Audio(data=audio, rate=24000, autoplay=i==0))
|
||||
# sf.write(f'{i}.wav', audio, 24000) # Save each audio segment
|
||||
# count += 1
|
||||
|
||||
# # Merge the individual WAV files into one
|
||||
# combined = AudioSegment.empty()
|
||||
# for i in range(count):
|
||||
# wav_path = os.path.join(script_directory, f"{i}.wav")
|
||||
# sound = AudioSegment.from_wav(wav_path)
|
||||
# combined += sound
|
||||
|
||||
# # Generate the output file name based on the source file name
|
||||
# base_name = os.path.splitext(os.path.basename(file_path))[0]
|
||||
# output_path = os.path.join(script_directory, f"{base_name}.wav")
|
||||
|
||||
# # Export the merged WAV file
|
||||
# combined.export(output_path, format="wav")
|
||||
# print(f"Merged WAV file saved as {output_path}")
|
||||
|
||||
# # Cleanup: Remove individual part files after merging
|
||||
# for i in range(count):
|
||||
# part_file = os.path.join(script_directory, f"{i}.wav")
|
||||
# if os.path.exists(part_file):
|
||||
# os.remove(part_file)
|
||||
# print(f"Removed {part_file}")
|
||||
|
||||
|
||||
|
||||
|
||||
# import os
|
||||
# import sys
|
||||
# import random
|
||||
# import string
|
||||
# from kokoro import KPipeline
|
||||
# from IPython.display import display, Audio
|
||||
# import soundfile as sf
|
||||
# from pydub import AudioSegment
|
||||
|
||||
# # Libraries for PDF and EPUB extraction
|
||||
# import PyPDF2
|
||||
# from ebooklib import epub
|
||||
# from bs4 import BeautifulSoup
|
||||
|
||||
# # Generate a random string for this process instance
|
||||
# random_str = ''.join(random.choices(string.ascii_lowercase + string.digits, k=8))
|
||||
# print(f"Random string for this process: {random_str}")
|
||||
|
||||
# # Get the directory of the current script
|
||||
# script_directory = os.path.dirname(os.path.abspath(sys.argv[0]))
|
||||
|
||||
# # Initialize the pipeline (ensure you have installed and set up kokoro correctly)
|
||||
# pipeline = KPipeline(lang_code='a')
|
||||
|
||||
# # Ask the user for the file path
|
||||
# print('Please input the file path (txt, pdf, or epub):')
|
||||
# file_path = input().strip()
|
||||
|
||||
# # Determine the file extension and prepare content
|
||||
# file_ext = os.path.splitext(file_path)[1].lower()
|
||||
# content = ''
|
||||
|
||||
# if file_ext == '.txt':
|
||||
# with open(file_path, 'r', encoding='utf-8') as file:
|
||||
# content = file.read()
|
||||
# elif file_ext == '.pdf':
|
||||
# with open(file_path, 'rb') as file:
|
||||
# reader = PyPDF2.PdfReader(file)
|
||||
# for page in reader.pages:
|
||||
# text = page.extract_text()
|
||||
# if text:
|
||||
# content += text + '\n'
|
||||
# elif file_ext == '.epub':
|
||||
# book = epub.read_epub(file_path)
|
||||
# for item in book.get_items():
|
||||
# if item.get_type() == epub.ITEM_DOCUMENT:
|
||||
# soup = BeautifulSoup(item.get_content(), 'html.parser')
|
||||
# text = soup.get_text()
|
||||
# content += text + '\n'
|
||||
# else:
|
||||
# print("Unsupported file format. Please provide a .txt, .pdf, or .epub file.")
|
||||
# sys.exit(1)
|
||||
|
||||
# # Optionally display the extracted content
|
||||
# print(content)
|
||||
|
||||
# # Generate the audio segments using the pipeline
|
||||
# generator = pipeline(
|
||||
# content, voice='af_bella', # Change voice if desired
|
||||
# speed=1, split_pattern=r'\n+'
|
||||
# )
|
||||
|
||||
# count = 0
|
||||
# # Save each segment with the random string in the filename
|
||||
# for i, (gs, ps, audio) in enumerate(generator):
|
||||
# part_filename = os.path.join(script_directory, f"{random_str}_{i}.wav")
|
||||
# print(i) # index of the segment
|
||||
# print(gs) # graphemes/text for this segment
|
||||
# print(ps) # phonemes for this segment
|
||||
# display(Audio(data=audio, rate=24000, autoplay=i==0))
|
||||
# sf.write(part_filename, audio, 24000) # Save each audio segment
|
||||
# count += 1
|
||||
|
||||
# # Merge the individual WAV files into one
|
||||
# combined = AudioSegment.empty()
|
||||
# for i in range(count):
|
||||
# part_file = os.path.join(script_directory, f"{random_str}_{i}.wav")
|
||||
# sound = AudioSegment.from_wav(part_file)
|
||||
# combined += sound
|
||||
|
||||
# # Generate the output file name based on the source file name
|
||||
# base_name = os.path.splitext(os.path.basename(file_path))[0]
|
||||
# output_path = os.path.join(script_directory, f"{base_name}.wav")
|
||||
|
||||
# # Export the merged WAV file
|
||||
# combined.export(output_path, format="wav")
|
||||
# print(f"Merged WAV file saved as {output_path}")
|
||||
|
||||
# # Cleanup: Remove individual part files after merging
|
||||
# for i in range(count):
|
||||
# part_file = os.path.join(script_directory, f"{random_str}_{i}.wav")
|
||||
# if os.path.exists(part_file):
|
||||
# os.remove(part_file)
|
||||
# print(f"Removed {part_file}")
|
||||
|
||||
|
||||
# import os
|
||||
# import sys
|
||||
# import random
|
||||
# import string
|
||||
# import re
|
||||
# from kokoro import KPipeline
|
||||
# from IPython.display import display, Audio
|
||||
# import soundfile as sf
|
||||
# from pydub import AudioSegment
|
||||
|
||||
# # Libraries for PDF and EPUB extraction
|
||||
# import PyPDF2
|
||||
# from ebooklib import epub
|
||||
# from bs4 import BeautifulSoup
|
||||
|
||||
# # Generate a random string for this process instance
|
||||
# random_str = ''.join(random.choices(string.ascii_lowercase + string.digits, k=8))
|
||||
# print(f"Random string for this process: {random_str}")
|
||||
|
||||
# # Get the directory of the current script
|
||||
# script_directory = os.path.dirname(os.path.abspath(sys.argv[0]))
|
||||
|
||||
# # Initialize the pipeline (ensure you have installed and set up kokoro correctly)
|
||||
# pipeline = KPipeline(lang_code='a')
|
||||
|
||||
# # Ask the user for the file path
|
||||
# print('Please input the file path (txt, pdf, or epub):')
|
||||
# file_path = input().strip()
|
||||
|
||||
# # Determine the file extension and prepare content
|
||||
# file_ext = os.path.splitext(file_path)[1].lower()
|
||||
# content = ''
|
||||
|
||||
# if file_ext == '.txt':
|
||||
# with open(file_path, 'r', encoding='utf-8') as file:
|
||||
# content = file.read()
|
||||
# elif file_ext == '.pdf':
|
||||
# with open(file_path, 'rb') as file:
|
||||
# reader = PyPDF2.PdfReader(file)
|
||||
# for page in reader.pages:
|
||||
# text = page.extract_text()
|
||||
# if text:
|
||||
# content += text + '\n'
|
||||
# elif file_ext == '.epub':
|
||||
# book = epub.read_epub(file_path)
|
||||
# from ebooklib.epub import EpubHtml # Import the document class
|
||||
# for item in book.get_items():
|
||||
# # Instead of checking for epub.ITEM_DOCUMENT, check if item is an instance of EpubHtml
|
||||
# if isinstance(item, EpubHtml):
|
||||
# soup = BeautifulSoup(item.get_content(), 'html.parser')
|
||||
# text = soup.get_text()
|
||||
# content += text + '\n'
|
||||
|
||||
# else:
|
||||
# print("Unsupported file format. Please provide a .txt, .pdf, or .epub file.")
|
||||
# sys.exit(1)
|
||||
|
||||
# # Optionally display the extracted content
|
||||
# print(content)
|
||||
|
||||
# # Combine all text into one large string by removing newline characters.
|
||||
# # This helps ensure the model receives larger chunks to work with.
|
||||
# content = ' '.join(content.splitlines())
|
||||
|
||||
# # Option 1: Let the model handle its own splitting by not providing a split pattern:
|
||||
# generator = pipeline(
|
||||
# content, voice='af_bella', # Change voice if desired
|
||||
# speed=1
|
||||
# )
|
||||
|
||||
# # Option 2: Alternatively, use a regex that splits on sentence boundaries (uncomment to use):
|
||||
# # generator = pipeline(
|
||||
# # content, voice='af_bella', # Change voice if desired
|
||||
# # speed=1, split_pattern=r'(?<=[.!?])\s+'
|
||||
# # )
|
||||
|
||||
# count = 0
|
||||
# # Save each segment with the random string in the filename
|
||||
# for i, (gs, ps, audio) in enumerate(generator):
|
||||
# part_filename = os.path.join(script_directory, f"{random_str}_{i}.wav")
|
||||
# print(i) # index of the segment
|
||||
# print(gs) # graphemes/text for this segment
|
||||
# print(ps) # phonemes for this segment
|
||||
# display(Audio(data=audio, rate=24000, autoplay=i==0))
|
||||
# sf.write(part_filename, audio, 24000) # Save each audio segment
|
||||
# count += 1
|
||||
|
||||
# # Merge the individual WAV files into one
|
||||
# combined = AudioSegment.empty()
|
||||
# for i in range(count):
|
||||
# part_file = os.path.join(script_directory, f"{random_str}_{i}.wav")
|
||||
# sound = AudioSegment.from_wav(part_file)
|
||||
# combined += sound
|
||||
|
||||
# # Generate the output file name based on the source file name
|
||||
# base_name = os.path.splitext(os.path.basename(file_path))[0]
|
||||
# output_path = os.path.join(script_directory, f"{base_name}.wav")
|
||||
|
||||
# # Export the merged WAV file
|
||||
# combined.export(output_path, format="wav")
|
||||
# print(f"Merged WAV file saved as {output_path}")
|
||||
|
||||
# # Cleanup: Remove individual part files after merging
|
||||
# for i in range(count):
|
||||
# part_file = os.path.join(script_directory, f"{random_str}_{i}.wav")
|
||||
# if os.path.exists(part_file):
|
||||
# os.remove(part_file)
|
||||
# print(f"Removed {part_file}")
|
||||
|
||||
|
||||
import os
|
||||
import sys
|
||||
import random
|
||||
import string
|
||||
import re
|
||||
from kokoro import KPipeline
|
||||
from IPython.display import display, Audio
|
||||
import soundfile as sf
|
||||
from pydub import AudioSegment
|
||||
|
||||
# Libraries for PDF and EPUB extraction
|
||||
import PyPDF2
|
||||
from ebooklib import epub
|
||||
from bs4 import BeautifulSoup
|
||||
items_phonemes = ['two.',
|
||||
'three.',
|
||||
'four.',
|
||||
'five.',
|
||||
'six.',
|
||||
'seven.',
|
||||
'eight.',
|
||||
'nine.',
|
||||
'ay.',
|
||||
'bee.',
|
||||
'dee.',
|
||||
'ee.',
|
||||
'eff.',
|
||||
'gee.',
|
||||
'aitch.',
|
||||
'jay.',
|
||||
'en.',
|
||||
'cue.',
|
||||
'are.',
|
||||
'tee.',
|
||||
'why.',
|
||||
'ay.',
|
||||
'bee.',
|
||||
'see.',
|
||||
'dee.',
|
||||
'ee.',
|
||||
'eff.',
|
||||
'gee.',
|
||||
'aitch.',
|
||||
'kay.',
|
||||
'ell.',
|
||||
'em.',
|
||||
'en.',
|
||||
'pee.',
|
||||
'cue.',
|
||||
'arr.',
|
||||
'ess.',
|
||||
'tee.',
|
||||
'you.',
|
||||
'vee.',
|
||||
'double you.',
|
||||
'ex.',
|
||||
'why.',
|
||||
'zee.']
|
||||
|
||||
items = ['2.','3.','4.','5.','6.','7.','8.','9.','a.','b.','d.','e.','f.','g.','h.','j.','n.','q.','r.','t.','y.','A.','B.','C.','D.','E.','F.','G.','H.','K.','L.','M.','N.','P.','Q.','R.','S.','T.','U.','V.','W.','X.','Y.','Z.']
|
||||
pipeline = KPipeline(lang_code='a')
|
||||
|
||||
for item, phoneme in zip(items, items_phonemes):
|
||||
print(item)
|
||||
generator = pipeline(
|
||||
phoneme, voice='af_bella', # Change voice if desired
|
||||
speed=0.8)
|
||||
for i, (gs, ps, audio) in enumerate(generator):
|
||||
part_filename = f"{item.lower()}wav"
|
||||
display(Audio(data=audio, rate=24000, autoplay=i==0))
|
||||
sf.write(f"captcha_audio/{part_filename}", audio, 24000) # Save each audio segment
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
exit()
|
||||
print(f"Random string for this process: {random_str}")
|
||||
|
||||
# Get the directory of the current script
|
||||
script_directory = os.path.dirname(os.path.abspath(sys.argv[0]))
|
||||
|
||||
# Initialize the pipeline (ensure you have installed and set up kokoro correctly)
|
||||
pipeline = KPipeline(lang_code='a')
|
||||
|
||||
# Ask the user for the file path
|
||||
print('Please input the file path (txt, pdf, or epub):')
|
||||
file_path = input().strip()
|
||||
|
||||
# Determine the file extension and prepare content
|
||||
file_ext = os.path.splitext(file_path)[1].lower()
|
||||
content = ''
|
||||
|
||||
if file_ext == '.txt':
|
||||
with open(file_path, 'r', encoding='utf-8') as file:
|
||||
content = file.read()
|
||||
elif file_ext == '.pdf':
|
||||
with open(file_path, 'rb') as file:
|
||||
reader = PyPDF2.PdfReader(file)
|
||||
for page in reader.pages:
|
||||
text = page.extract_text()
|
||||
if text:
|
||||
content += text + '\n'
|
||||
elif file_ext == '.epub':
|
||||
book = epub.read_epub(file_path)
|
||||
from ebooklib.epub import EpubHtml # Use EpubHtml for document-type items
|
||||
for item in book.get_items():
|
||||
if isinstance(item, EpubHtml):
|
||||
soup = BeautifulSoup(item.get_content(), 'html.parser')
|
||||
text = soup.get_text()
|
||||
content += text + '\n'
|
||||
else:
|
||||
print("Unsupported file format. Please provide a .txt, .pdf, or .epub file.")
|
||||
sys.exit(1)
|
||||
|
||||
# Optionally display the extracted content
|
||||
print(content)
|
||||
|
||||
# Remove all instances of "OceanofPDF.com" from the content
|
||||
content = content.replace("OceanofPDF.com", "")
|
||||
|
||||
# Combine all text into one large string by removing newline characters.
|
||||
# This helps ensure the model receives larger chunks to work with.
|
||||
content = ' '.join(content.splitlines())
|
||||
|
||||
# Option 1: Let the model handle its own splitting by not providing a split pattern:
|
||||
generator = pipeline(
|
||||
content, voice='af_heart', # Change voice if desired
|
||||
speed=0.8
|
||||
)
|
||||
|
||||
# Option 2: Alternatively, use a regex that splits on sentence boundaries (uncomment to use):
|
||||
# generator = pipeline(
|
||||
# content, voice='af_bella', # Change voice if desired
|
||||
# speed=1, split_pattern=r'(?<=[.!?])\s+'
|
||||
# )
|
||||
|
||||
count = 0
|
||||
# Save each segment with the random string in the filename
|
||||
for i, (gs, ps, audio) in enumerate(generator):
|
||||
part_filename = os.path.join(script_directory, f"{random_str}_{i}.wav")
|
||||
print(i) # index of the segment
|
||||
print(gs) # graphemes/text for this segment
|
||||
print(ps) # phonemes for this segment
|
||||
display(Audio(data=audio, rate=24000, autoplay=i==0))
|
||||
sf.write(part_filename, audio, 24000) # Save each audio segment
|
||||
count += 1
|
||||
|
||||
# Merge the individual WAV files into one
|
||||
combined = AudioSegment.empty()
|
||||
for i in range(count):
|
||||
part_file = os.path.join(script_directory, f"{random_str}_{i}.wav")
|
||||
sound = AudioSegment.from_wav(part_file)
|
||||
combined += sound
|
||||
|
||||
# Generate the output file name based on the source file name
|
||||
base_name = os.path.splitext(os.path.basename(file_path))[0]
|
||||
output_path = os.path.join(script_directory, f"{base_name}.wav")
|
||||
|
||||
# Export the merged WAV file
|
||||
combined.export(output_path, format="wav")
|
||||
print(f"Merged WAV file saved as {output_path}")
|
||||
|
||||
# Cleanup: Remove individual part files after merging
|
||||
for i in range(count):
|
||||
part_file = os.path.join(script_directory, f"{random_str}_{i}.wav")
|
||||
if os.path.exists(part_file):
|
||||
os.remove(part_file)
|
||||
print(f"Removed {part_file}")
|
||||
|
||||
48
script.txt
48
script.txt
@@ -1,42 +1,46 @@
|
||||
How to Sign Up for a Shift in the New Faculty Proctor Scheduling Application...
|
||||
How to Sign Up for a Shift in the New Faculty Proctor Scheduling Application......
|
||||
|
||||
first, Log into the portal.
|
||||
first, Log into the portal....
|
||||
|
||||
Once you’ve logged in, navigate to the Available Assessments page by selecting the link in the navigation.
|
||||
Once you’ve logged in, navigate to the Available Assessments page by selecting the link in the navigation....
|
||||
|
||||
On the Available Assessments page, you’ll see a table showing all assessments currently available to you. This includes assessments within the organization you have access to, as well as any assessments that have been shared with all proctors.
|
||||
On the Available Assessments page, you’ll see a table showing all assessments currently available to you.... This includes assessments within the organization you have access to, as well as any assessments that have been shared with all proctors......
|
||||
|
||||
In this example, I am set up as a proctor for the Department of Management and Organizational Studies under Social Science. I can see assessments under that organization, and I can also see that one assessment from Economics has been shared with all proctors.
|
||||
In this example, I am set up as a proctor for the Department of Management and Organizational Studies under Social Science.. I can see assessments under that organization, and I can also see that one assessment from Economics has been shared with all proctors....
|
||||
|
||||
When signing up for an assessment, you can see whether there are notes associated with it by checking the Notes Present column in the table. If a note exists, the column will say “Yes.” You can view the note by clicking the magnifying-glass icon.
|
||||
When signing up for an assessment, you can see whether there are notes associated with it by checking the Notes Present column in the table.. If a note exists, the column will say “Yes..” You can view the note by clicking the magnifying-glass icon....
|
||||
|
||||
After clicking the magnifying-glass icon, you’ll see assessment details and any notes associated with that assessment. The note may have been added by your faculty administrator or imported from our Exam Central system, where it would have been visible to students.
|
||||
After clicking the magnifying-glass icon, you’ll see assessment details and any notes associated with that assessment.. The note may have been added by your faculty administrator or imported from our Exam Central system, where it would have been visible to students....
|
||||
|
||||
From this page, you can return to the Available Assessments page or add the assessment to your schedule by clicking the purple Add to My Schedule button.
|
||||
From this page, you can return to the Available Assessments page or add the assessment to your schedule by clicking the purple Add to My Schedule button....
|
||||
|
||||
I’ll add this one to my schedule, and then I’ll show you how to add assessments directly from the Available Assessments page.
|
||||
I’ll add this one to my schedule, and then I’ll show you how to add assessments directly from the Available Assessments page....
|
||||
|
||||
When adding an assessment from the magnifying-glass view, you can return to the Available Assessments page by clicking the blue button, or go to your schedule by clicking the purple button. I’ll click the blue button to go back.
|
||||
When adding an assessment from the magnifying-glass view, you can return to the Available Assessments page by clicking the blue button, or go to your schedule by clicking the purple button.. I’ll click the blue button to go back....
|
||||
|
||||
Now that we’re back on the Available Assessments page, you can quickly add assessments to your schedule by clicking the blue Sign Up button on the right side of the row.
|
||||
Now that we’re back on the Available Assessments page, you can quickly add assessments to your schedule by clicking the blue Sign Up button on the right side of the row....
|
||||
|
||||
I’ll add one of these assessments now.
|
||||
I’ll add one of these assessments now....
|
||||
|
||||
When an assessment is added to your schedule, any other assessments that overlap with that time block are automatically removed from the Available Assessments page. The system prevents overlapping bookings to help ensure you don’t overbook yourself.
|
||||
When an assessment is added to your schedule, any other assessments that overlap with that time block are automatically removed from the Available Assessments page.. The system prevents overlapping bookings to help ensure you don’t overbook yourself....
|
||||
|
||||
Next, I’ll navigate to the Assessment Schedule. You can open this page using the link in the navigation.
|
||||
You will also receive an email confirming you've signed up for the shift....
|
||||
|
||||
On the Assessment Schedule page, you’ll see your upcoming assessments ordered by their start date. You can also open the magnifying-glass view from the upcoming assessments table, the past assessments table, and the archived assessments table to review details at any time.
|
||||
Next, I’ll navigate to the Assessment Schedule.. You can open this page using the link in the navigation....
|
||||
|
||||
If you are no longer able to work an assessment you signed up for, you can click the purple Cancel button in the upcoming assessments table to cancel the shift. This option is not available within the 72-hour window before the shift. If you need to cancel during that 72-hour window, contact your faculty administrator and they will be able to remove you.
|
||||
On the Assessment Schedule page, you’ll see your upcoming assessments ordered by their start date.. You can also open the magnifying-glass view from the upcoming assessments table, the past assessments table, and the archived assessments table to review details at any time....
|
||||
|
||||
After completing a shift, you will need to complete a Shift and Report. You can do this from the Past Assessments table. In the right-hand column, you’ll see a Shift and Report button. Click this to complete the report.
|
||||
If you are no longer able to work an assessment you signed up for, you can click the purple Cancel button in the upcoming assessments table to cancel the shift.. This option is not available within the 72-hour window before the shift.. If you need to cancel during that 72-hour window, contact your faculty administrator and they will be able to remove you....
|
||||
|
||||
In the Shift and Report form, you can review the assessment details and then choose the attendance, actual start time, actual end time, and add any notes.
|
||||
If you arrived early because it was required, adjust the actual start time accordingly. If you had to stay late, adjust the actual end time as well. This information is included in the report sent to your faculty administrator.
|
||||
After canceling a shift, you will receive an email to confirm that you have canceled a shift....
|
||||
|
||||
If you did not attend, if you showed up but were sent home, or if you worked your shift normally, select the appropriate attendance option. You may add notes to give more context to your faculty administrator.
|
||||
After completing a shift, you will need to complete a Shift End Report.. You can do this from the Past Assessments table.. In the right-hand column, you’ll see a Shift End Report button.. Click this to complete the report....
|
||||
|
||||
When you’re finished, click Submit Report. Your report will be available to your faculty administrator for review, and your hours will be accessible to them.
|
||||
In the Shift End Report form, you can review the assessment details and then choose the attendance, actual start time, actual end time, and add any notes..
|
||||
If you arrived early because it was required, adjust the actual start time accordingly.. If you had to stay late, adjust the actual end time as well.. This information is included in the report sent to your faculty administrator....
|
||||
|
||||
This concludes how to sign up for a shift as a proctor in the new Faculty Proctor Scheduling system.
|
||||
If you did not attend, if you showed up but were sent home, or if you worked your shift normally, select the appropriate attendance option.. You may add notes to give more context to your faculty administrator....
|
||||
|
||||
When you’re finished, click Submit Report.. Your report will be available to your faculty administrator for review, and your hours will be accessible to them....
|
||||
|
||||
This concludes how to sign up for a shift as a proctor in the new Faculty Proctor Scheduling system....
|
||||
BIN
script.wav
BIN
script.wav
Binary file not shown.
34
script2.txt
Normal file
34
script2.txt
Normal file
@@ -0,0 +1,34 @@
|
||||
How to Add an Assessment as an Administrator in the faculty proctor scheduling administration application....
|
||||
|
||||
First, navigate to the Proctor Scheduling System’s Administrative Portal within Extranet....
|
||||
|
||||
From the navigation, select the Assessments tab, and then choose Assessment Management....
|
||||
|
||||
On the Assessment Management page, you’ll see an Add Assessment button below the Assessments table....
|
||||
Click this button to open the form used to create a new assessment....
|
||||
|
||||
To create the assessment, begin by selecting an organization for the assessment to fall under....
|
||||
|
||||
Next, fill out the Assessment Name field....
|
||||
|
||||
Then fill out the Assessment Type field....
|
||||
If the type you need is not present in the dropdown, choose Other and enter the new type in the field that appears.... The next time you use this form, your newly added type will appear in the list....
|
||||
|
||||
Add any assessment notes.... These notes will be visible to proctors....
|
||||
|
||||
Fill out the Building field and the Room Number field....
|
||||
Both are required.... If you’re unsure of the building or room when creating the assessment, we recommend entering “To Be Determined” or “TBD....”
|
||||
|
||||
After that, fill in the Start Date and Time, End Date and Time, the Number of Proctors Required, and—if available—either the Instructor Email, or the Acad Career, Term, and Class Number....
|
||||
If you provide the Acad Career, Term, and Class Number, you do not need to include the instructor’s email.... The system will pull the instructor information from PeopleSoft using those values....
|
||||
If you don’t have those three values, then you’ll need to provide the instructor email....
|
||||
|
||||
Finally, if you want the assessment to be available to all proctors, check the Available to All Proctors checkbox....
|
||||
Checking this will make the assessment visible to every active proctor in the system....
|
||||
If you only want proctors in the assigned organization to see it, leave this box unchecked....
|
||||
|
||||
Once you’re satisfied with everything you’ve entered, click the Add Assessment button....
|
||||
|
||||
If the assessment is created successfully, you’ll see a confirmation message stating that it was added.... From there, you can return to the Manage Assessments page by clicking the grey Back to Manage Assessments button....
|
||||
|
||||
That concludes how to add an assessment in the new Faculty Proctor Scheduling System....
|
||||
BIN
script2.wav
Normal file
BIN
script2.wav
Normal file
Binary file not shown.
@@ -11,7 +11,7 @@ from kokoro import KPipeline # Assuming you have this library available
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
selected_voice = "am_adam"
|
||||
selected_voice = "am_fenrir"
|
||||
|
||||
# Initialize the pipeline at app startup so it doesn’t re-initialize for every request
|
||||
try:
|
||||
|
||||
354
subtitles.srt
Normal file
354
subtitles.srt
Normal file
@@ -0,0 +1,354 @@
|
||||
1
|
||||
00:00:05,000 --> 00:00:10,567
|
||||
How to Sign Up for a Shift in the New Faculty Proctor Scheduling
|
||||
Application.
|
||||
|
||||
2
|
||||
00:00:10,568 --> 00:00:13,699
|
||||
first, Log into the portal.
|
||||
|
||||
3
|
||||
00:00:14,000 --> 00:00:16,979
|
||||
Once you’ve logged in,
|
||||
navigate to the Available
|
||||
|
||||
4
|
||||
00:00:17,003 --> 00:00:20,681
|
||||
Assessments page by
|
||||
selecting the link in the navigation.
|
||||
|
||||
5
|
||||
00:00:20,700 --> 00:00:24,643
|
||||
On the Available Assessments
|
||||
page, you’ll see a table
|
||||
|
||||
6
|
||||
00:00:24,667 --> 00:00:28,610
|
||||
showing all assessments
|
||||
currently available to you.
|
||||
|
||||
7
|
||||
00:00:28,611 --> 00:00:33,499
|
||||
This includes assessments within
|
||||
the organization you have access to,
|
||||
|
||||
8
|
||||
00:00:33,523 --> 00:00:38,410
|
||||
as well as any assessments that
|
||||
have been shared with all proctors.
|
||||
|
||||
9
|
||||
00:00:39,000 --> 00:00:43,387
|
||||
In this example, I am set up
|
||||
as a proctor for the Department
|
||||
|
||||
10
|
||||
00:00:43,411 --> 00:00:47,797
|
||||
of Management and Organizational
|
||||
Studies under Social Science.
|
||||
|
||||
11
|
||||
00:00:48,000 --> 00:00:52,599
|
||||
I can see assessments under
|
||||
that organization, and I can also see
|
||||
|
||||
12
|
||||
00:00:52,623 --> 00:00:57,655
|
||||
that one assessment from Economics
|
||||
has been shared with all proctors.
|
||||
|
||||
13
|
||||
00:00:58,000 --> 00:01:02,295
|
||||
When signing up for an assessment,
|
||||
you can see whether there are notes
|
||||
|
||||
14
|
||||
00:01:02,319 --> 00:01:06,613
|
||||
associated with it by checking the
|
||||
Notes Present column in the table.
|
||||
|
||||
15
|
||||
00:01:06,614 --> 00:01:11,057
|
||||
If a note exists, the column
|
||||
will say “Yes.” You can
|
||||
|
||||
16
|
||||
00:01:11,081 --> 00:01:15,524
|
||||
view the note by clicking
|
||||
the magnifying-glass icon.
|
||||
|
||||
17
|
||||
00:01:15,600 --> 00:01:20,060
|
||||
After clicking the magnifying-glass
|
||||
icon, you’ll see assessment
|
||||
|
||||
18
|
||||
00:01:20,084 --> 00:01:24,039
|
||||
details and any notes
|
||||
associated with that assessment.
|
||||
|
||||
19
|
||||
00:01:24,100 --> 00:01:28,008
|
||||
The note may have been added by
|
||||
your faculty administrator or imported
|
||||
|
||||
20
|
||||
00:01:28,032 --> 00:01:31,770
|
||||
from our Exam Central system,
|
||||
where it would have been visible to
|
||||
|
||||
21
|
||||
00:01:31,794 --> 00:01:34,342
|
||||
students.
|
||||
|
||||
22
|
||||
00:01:34,400 --> 00:01:38,486
|
||||
From this page, you can return to
|
||||
the Available Assessments page or
|
||||
|
||||
23
|
||||
00:01:38,510 --> 00:01:42,595
|
||||
add the assessment to your schedule
|
||||
by clicking the purple Add to My
|
||||
|
||||
24
|
||||
00:01:42,619 --> 00:01:45,343
|
||||
Schedule button.
|
||||
|
||||
25
|
||||
00:01:45,400 --> 00:01:49,508
|
||||
I’ll add this one to my schedule,
|
||||
and then I’ll show you how to
|
||||
|
||||
26
|
||||
00:01:49,532 --> 00:01:53,640
|
||||
add assessments directly from
|
||||
the Available Assessments page.
|
||||
|
||||
27
|
||||
00:01:53,641 --> 00:01:57,599
|
||||
When adding an assessment from
|
||||
the magnifying-glass view, you can
|
||||
|
||||
28
|
||||
00:01:57,623 --> 00:02:01,953
|
||||
return to the Available Assessments
|
||||
page by clicking the blue button,
|
||||
|
||||
29
|
||||
00:02:01,977 --> 00:02:05,258
|
||||
or go to your schedule by
|
||||
clicking the purple button.
|
||||
|
||||
30
|
||||
00:02:05,300 --> 00:02:08,018
|
||||
I’ll click the blue button to go back.
|
||||
|
||||
31
|
||||
00:02:08,019 --> 00:02:11,971
|
||||
Now that we’re back on the Available
|
||||
Assessments page, you can quickly
|
||||
|
||||
32
|
||||
00:02:11,995 --> 00:02:15,947
|
||||
add assessments to your schedule
|
||||
by clicking the blue Sign Up button
|
||||
|
||||
33
|
||||
00:02:15,971 --> 00:02:18,606
|
||||
on the right side of the row.
|
||||
|
||||
34
|
||||
00:02:18,700 --> 00:02:21,718
|
||||
I’ll add one of these assessments now.
|
||||
|
||||
35
|
||||
00:02:21,800 --> 00:02:26,181
|
||||
When an assessment is added to
|
||||
your schedule, any other assessments
|
||||
|
||||
36
|
||||
00:02:26,205 --> 00:02:30,586
|
||||
that overlap with that time block
|
||||
are automatically removed from the
|
||||
|
||||
37
|
||||
00:02:30,610 --> 00:02:33,530
|
||||
Available Assessments page.
|
||||
|
||||
38
|
||||
00:02:33,540 --> 00:02:39,547
|
||||
The system prevents overlapping bookings
|
||||
to help ensure you don’t overbook yourself.
|
||||
|
||||
39
|
||||
00:02:39,548 --> 00:02:44,769
|
||||
You will also receive an email
|
||||
confirming you've signed up for the shift.
|
||||
|
||||
40
|
||||
00:02:44,770 --> 00:02:48,132
|
||||
Next, I’ll navigate to the
|
||||
Assessment Schedule.
|
||||
|
||||
41
|
||||
00:02:48,133 --> 00:02:53,138
|
||||
You can open this page
|
||||
using the link in the navigation.
|
||||
|
||||
42
|
||||
00:02:53,139 --> 00:02:56,632
|
||||
On the Assessment
|
||||
Schedule page, you’ll see your
|
||||
|
||||
43
|
||||
00:02:56,656 --> 00:03:00,148
|
||||
upcoming assessments
|
||||
ordered by their start date.
|
||||
|
||||
44
|
||||
00:03:00,149 --> 00:03:04,797
|
||||
You can also open the
|
||||
magnifying-glass view from the upcoming
|
||||
|
||||
45
|
||||
00:03:04,821 --> 00:03:09,469
|
||||
assessments table, the past
|
||||
assessments table, and the archived
|
||||
|
||||
46
|
||||
00:03:09,493 --> 00:03:13,094
|
||||
assessments table to
|
||||
review details at any time.
|
||||
|
||||
47
|
||||
00:03:13,100 --> 00:03:17,373
|
||||
If you are no longer able to work
|
||||
an assessment you signed up for, you
|
||||
|
||||
48
|
||||
00:03:17,397 --> 00:03:21,670
|
||||
can click the purple Cancel button
|
||||
in the upcoming assessments table
|
||||
|
||||
49
|
||||
00:03:21,694 --> 00:03:24,543
|
||||
to cancel the shift.
|
||||
|
||||
50
|
||||
00:03:24,544 --> 00:03:29,694
|
||||
This option is not available within
|
||||
the 72-hour window before the shift.
|
||||
|
||||
51
|
||||
00:03:29,695 --> 00:03:34,082
|
||||
If you need to cancel during
|
||||
that 72-hour window, contact your
|
||||
|
||||
52
|
||||
00:03:34,106 --> 00:03:38,349
|
||||
faculty administrator and
|
||||
they will be able to remove you.
|
||||
|
||||
53
|
||||
00:03:38,350 --> 00:03:41,447
|
||||
After canceling a
|
||||
shift, you will receive an
|
||||
|
||||
54
|
||||
00:03:41,471 --> 00:03:45,001
|
||||
email to confirm that
|
||||
you have canceled a shift.
|
||||
|
||||
55
|
||||
00:03:45,002 --> 00:03:49,880
|
||||
After completing a shift, you will
|
||||
need to complete a Shift End Report.
|
||||
|
||||
56
|
||||
00:03:49,888 --> 00:03:53,321
|
||||
You can do this from the
|
||||
Past Assessments table.
|
||||
|
||||
57
|
||||
00:03:53,323 --> 00:03:57,829
|
||||
In the right-hand column, you’ll
|
||||
see a Shift End Report button.
|
||||
|
||||
58
|
||||
00:03:57,830 --> 00:04:00,262
|
||||
Click this to complete the report.
|
||||
|
||||
59
|
||||
00:04:00,270 --> 00:04:04,720
|
||||
In the Shift End Report form, you
|
||||
can review the assessment details
|
||||
|
||||
60
|
||||
00:04:04,744 --> 00:04:09,194
|
||||
and then choose the attendance,
|
||||
actual start time, actual end time,
|
||||
|
||||
61
|
||||
00:04:09,218 --> 00:04:12,184
|
||||
and add any notes.
|
||||
|
||||
62
|
||||
00:04:12,188 --> 00:04:15,323
|
||||
If you arrived early
|
||||
because it was required,
|
||||
|
||||
63
|
||||
00:04:15,347 --> 00:04:18,410
|
||||
adjust the actual
|
||||
start time accordingly.
|
||||
|
||||
64
|
||||
00:04:18,420 --> 00:04:22,712
|
||||
If you had to stay late, adjust
|
||||
the actual end time as well.
|
||||
|
||||
65
|
||||
00:04:22,713 --> 00:04:28,291
|
||||
This information is included in the
|
||||
report sent to your faculty administrator.
|
||||
|
||||
66
|
||||
00:04:28,300 --> 00:04:33,259
|
||||
If you did not attend, if you showed
|
||||
up but were sent home, or if you
|
||||
|
||||
67
|
||||
00:04:33,283 --> 00:04:38,242
|
||||
worked your shift normally, select
|
||||
the appropriate attendance option.
|
||||
|
||||
68
|
||||
00:04:38,243 --> 00:04:43,178
|
||||
You may add notes to give more
|
||||
context to your faculty administrator.
|
||||
|
||||
69
|
||||
00:04:43,178 --> 00:04:46,181
|
||||
When you’re finished, click Submit Report.
|
||||
|
||||
70
|
||||
00:04:46,181 --> 00:04:50,354
|
||||
Your report will be available
|
||||
to your faculty administrator
|
||||
|
||||
71
|
||||
00:04:50,378 --> 00:04:54,335
|
||||
for review, and your hours
|
||||
will be accessible to them.
|
||||
|
||||
72
|
||||
00:04:54,335 --> 00:04:57,574
|
||||
This concludes how to
|
||||
sign up for a shift as a
|
||||
|
||||
73
|
||||
00:04:57,598 --> 00:05:01,487
|
||||
proctor in the new Faculty
|
||||
Proctor Scheduling system.
|
||||
|
||||
Reference in New Issue
Block a user