Two .NET 10 applications work together:
SpeechServices.Cli: downloads or reads audio, normalizes it to WAV, and transcribes it with Azure AI Speech.SpeechServices.Wpf: WPF desktop GUI that launches the CLI in the background, streams progress, previews transcript text, and saves the text file.
- Windows with .NET 10 SDK/runtime.
- Azure AI Speech resource key and region.
- Internet access for Azure Speech and YouTube URL input.
- Local audio must be decodable by Windows Media Foundation. WAV, MP3, and M4A are the safest choices.
dotnet build .\SpeechServices.slnThe WPF build copies the CLI output into:
SpeechServices.Wpf\bin\Debug\net10.0-windows7.0\cli\
| Setting | CLI argument | Environment variable | GUI field | Example |
|---|---|---|---|---|
| Azure Speech key | --speech-key |
AZURE_SPEECH_KEY |
Key | xxxxxxxx |
| Azure Speech region | --speech-region |
AZURE_SPEECH_REGION |
Region | eastus |
| Input source | --input |
none | Source | sample.mp3 or YouTube URL |
| Input type | --input-type |
none | Input type | auto, file, youtube |
| Speech language | --language |
none | Language | en-US, pl-PL |
| Speaker count | --speakers |
none | Speakers | 1, 2 |
The WPF application can preload GUI fields from a JSON file. The CLI does not read this file; when the GUI starts transcription, it passes the current GUI values to the CLI as normal command-line arguments and environment variables. The default filename is transcription.config.json; a sample is provided in transcription.config.sample.json. The WPF app also saves the current Speech key, region, language, and speaker count when it closes. Its per-user settings file is stored in %LocalAppData%\SpeechServices\settings.json; the Speech key is protected with Windows DPAPI.
{
"videoUrl": "https://www.youtube.com/watch?v=VIDEO_ID",
"inputType": "youtube",
"speechRegion": "eastus",
"speechKey": "<your-azure-speech-key>",
"language": "en-US",
"speakers": 1
}Supported aliases:
inputorvideoUrlfor the source.speechKeyorazureKeyfor the Azure Speech key.speechRegionorregionfor the Azure Speech region.
When speaker count is greater than 1, the CLI uses Azure ConversationTranscriber so transcript segments can include speaker labels. Azure assigns speaker identifiers automatically; the value does not force an exact number of speakers.
Set credentials:
$env:AZURE_SPEECH_KEY = "<your-speech-key>"
$env:AZURE_SPEECH_REGION = "eastus"Transcribe a local file:
dotnet run --project .\SpeechServices.Cli -- --input .\sample.mp3 --language en-US --output .\transcript.txtTranscribe a YouTube URL with JSON progress:
.\SpeechServices.Cli\bin\Debug\net10.0-windows7.0\SpeechServices.Cli.exe `
--input "https://www.youtube.com/watch?v=VIDEO_ID" `
--input-type youtube `
--language en-US `
--speakers 2 `
--jsonUseful CLI options:
--output <path> Save final transcript from the CLI.
--work-dir <path> Directory for downloaded and converted audio.
--keep-temp Keep temporary audio files for troubleshooting.
--json Emit newline-delimited JSON events for GUI/process integration.
- Run
SpeechServices.Wpf. - Provide a local audio file or YouTube URL, or browse to a JSON configuration file.
- Enter Azure Speech key and region, set
AZURE_SPEECH_KEYandAZURE_SPEECH_REGION, or load them from the configuration file. - Set language and speaker count.
- Click
Start. - Review progress and transcript preview.
- Click
Save Text...to save the previewed transcript.
If processing fails, right-click the progress log and choose Copy Error Output to copy the run output and diagnostic details to the clipboard.
The GUI passes credentials to the CLI through process environment variables so the Speech key is not placed on the command line.
The WPF interface is declared in MainWindow.xaml, with the process integration in its code-behind. This keeps the layout editable in the WPF designer while retaining the CLI-based transcription workflow.
With --json, the CLI writes newline-delimited JSON to stdout. Event type values are:
status: stage progress such as download, conversion, and recognition session state.partial: intermediate recognition text.segment: final transcript segment with optionalspeakerId,offsetMs, anddurationMs.completed: final transcript text and optional output path.error: failure message and details.
- YouTube input uses
YoutubeExplodeto download the best audio-only stream, preferring MP4/M4A because Windows Media Foundation usually decodes it reliably. - Audio conversion uses
NAudioto create 16 kHz, 16-bit, mono PCM WAV before calling the Azure Speech SDK. - Azure Speech usage may incur costs in the Azure subscription that owns the Speech resource.
- Product and SDK documentation: Azure AI Speech, Azure Speech SDK samples, YoutubeExplode, NAudio.