最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于Go語言編寫一個能在Windows上錄音的小程序

 更新時間:2026年03月03日 09:55:07   作者:Mgx  
這篇文章主要為大家詳細(xì)介紹了如何基于Go語言編寫一個能在Windows上錄音的小程序,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

大家好!今天我要帶大家用 Go 語言寫一個能在 Windows 上錄音的小程序。別緊張,這不是什么黑客工具(雖然聽起來有點(diǎn)像),而是一個正經(jīng)的、能生成 output.wav 文件的"聲音捕捉器"——比如錄下你早上對著電腦喊"為什么又報錯了!"的珍貴瞬間 。

使用的Go庫

這個項目用到了兩個非??岬?Go 庫:

  • github.com/Onelio/winmm:讓你在 Windows 上調(diào)用經(jīng)典的 winmm.dll 多媒體 API(沒錯,就是那個 Win95 時代就存在的老古董,但它依然好用?。?/li>
  • github.com/go-audio/wav:幫你把原始音頻數(shù)據(jù)打包成標(biāo)準(zhǔn)的 WAV 文件。

話不多說,咱們直接上"操作"!

第一步:看看你的電腦有哪些"耳朵"和"嘴巴"

程序啟動后,它會先列出你電腦上所有的輸入設(shè)備(麥克風(fēng))和輸出設(shè)備(揚(yáng)聲器):

輸入設(shè)備: 0 麥克風(fēng) (Realtek Audio)
輸入設(shè)備: 1 立體聲混音 (Realtek Audio)
輸出設(shè)備: 0 揚(yáng)聲器 (Realtek Audio)
輸出設(shè)備: 1 耳機(jī) (Bluetooth Device)

然后它會壞笑著等你按回車——仿佛在說:"準(zhǔn)備好了嗎?我要開始偷聽你了哦~"

第二步:開始錄音

程序會以 8kHz 采樣率、16位深度、立體聲 的格式錄音。雖然音質(zhì)比不上 Hi-Res,但錄個語音備忘、貓叫、或者你模仿 Siri 的聲音綽綽有余。

錄音過程中,你隨時按回車就能停止。程序會把錄到的所有聲音,乖乖寫進(jìn)一個叫 output.wav 的文件里。

小知識:8kHz 是電話音質(zhì),但對語音識別或簡單錄音完全夠用,而且文件?。?/p>

第三步:播放你的"高光時刻"

錄完后,雙擊 output.wav,Windows 自帶的播放器就會打開。

  • 如果你錄的是"啊——測試測試",那恭喜你,成功了!
  • 如果你錄的是"老板根本不懂技術(shù)",建議立刻刪除文件并裝作無事發(fā)生 。

為什么這個代碼有點(diǎn)"復(fù)古"?

因為底層用的是 Windows 的 WaveIn API,這可是上世紀(jì) 90 年代的產(chǎn)物!但它穩(wěn)定、簡單、無需管理員權(quán)限,特別適合做小型錄音工具。Go 語言通過 cgo 或 syscall 封裝后,用起來居然還挺順手。

不過要注意:這段代碼只能在 Windows 上跑。Mac 和 Linux 用戶請繞道,或者考慮用 PortAudio 之類的跨平臺庫。

完整源碼

下面就是我們精心整理、注釋全中文、風(fēng)格清爽的錄音小工具源碼:

package main

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"io"
	"log"
	"os"
	"time"

	"github.com/Onelio/winmm"
	"github.com/go-audio/audio"
	"github.com/go-audio/wav"
)

func main() {
	// 列出所有輸入設(shè)備
	inputDevices, _ := winmm.EnumInDevices()
	for _, dev := range inputDevices {
		fmt.Println("輸入設(shè)備:", dev.Id(), dev.Name())
	}

	// 列出所有輸出設(shè)備
	outputDevices, _ := winmm.EnumOutDevices()
	for _, dev := range outputDevices {
		fmt.Println("輸出設(shè)備:", dev.Id(), dev.Name())
	}

	// 等待用戶按回車?yán)^續(xù)
	fmt.Println("按回車鍵開始錄音...")
	_, _ = fmt.Scanln()

	// 1. 創(chuàng)建錄音所需的音頻格式:立體聲(2通道)、8kHz 采樣率、16位深度
	waveFormat := winmm.NewWaveFormat(winmm.ChStereo, winmm.SpS08kHz, winmm.BpS16)

	// 創(chuàng)建用于錄音的緩沖區(qū),時長為 2 秒
	recordBuffer := winmm.NewWaveHeader(waveFormat, 2)

	// 創(chuàng)建錄音對象并打開默認(rèn)錄音設(shè)備(WaveMapper)
	recorder := winmm.NewWaveIn()
	_ = recorder.Open(winmm.WaveMapper, waveFormat)

	// 準(zhǔn)備緩沖區(qū),并獲取其唯一標(biāo)識 key(用于后續(xù)操作)
	bufferKey, _ := recorder.PrepareBuffer(recordBuffer)

	fmt.Println("正在錄音...(按回車鍵停止)")

	// 將緩沖區(qū)添加到錄音設(shè)備,并開始錄音
	_ = recorder.AddBuffer(bufferKey)
	_ = recorder.Start()

	// 稍微延遲,確保錄音已開始
	time.Sleep(200 * time.Millisecond)

	// 啟動一個 goroutine,監(jiān)聽用戶是否按下回車鍵以停止錄音
	shouldStop := false
	go func() {
		_, _ = fmt.Scanln()
		shouldStop = true
	}()

	// 創(chuàng)建輸出 WAV 文件
	outFile, err := os.Create("output.wav")
	if err != nil {
		log.Fatal("無法創(chuàng)建輸出文件:", err)
	}
	defer outFile.Close()

	// 創(chuàng)建 WAV 編碼器:8kHz、16位、2通道(立體聲)、1 塊(通常為 1)
	encoder := wav.NewEncoder(outFile, 8000, 16, 2, 1)

	// 初始化用于寫入的音頻緩沖區(qū)
	writeBuffer := audio.IntBuffer{
		Format: &audio.Format{
			NumChannels: 2,   // 立體聲
			SampleRate:  8000, // 8kHz 采樣率
		},
	}

	// 持續(xù)監(jiān)聽錄音數(shù)據(jù),直到用戶停止
	for !shouldStop {
		select {
		case data := <-recorder.Channel:
			// 將接收到的原始字節(jié)數(shù)據(jù)轉(zhuǎn)換為 int16 樣本,并追加到 writeBuffer
			copyDataToBuffer(data.GetBufferSlice(), &writeBuffer)
			// 重新將緩沖區(qū)加入錄音隊列(循環(huán)使用)
			_ = recorder.AddBuffer(bufferKey)
			_ = recorder.Start()
		default:
			// 短暫休眠,避免忙等待
			time.Sleep(10 * time.Millisecond)
		}
	}

	// 停止錄音后,釋放緩沖區(qū)
	_ = recorder.UnPrepareBuffer(bufferKey)
	// 關(guān)閉錄音設(shè)備
	_ = recorder.Close()

	// 將錄制的音頻數(shù)據(jù)寫入 WAV 文件(包含 RIFF 頭和 PCM 數(shù)據(jù))
	if err := encoder.Write(&writeBuffer); err != nil {
		log.Fatal("寫入 WAV 文件失敗:", err)
	}
	if err := encoder.Close(); err != nil {
		log.Fatal("關(guān)閉 WAV 編碼器失敗:", err)
	}

	fmt.Println("錄音已保存為 output.wav")
}

// copyDataToBuffer 將原始字節(jié)數(shù)據(jù)(小端序 int16)轉(zhuǎn)換為 audio.IntBuffer 所需的 int 切片
func copyDataToBuffer(data []byte, buffer *audio.IntBuffer) {
	reader := bytes.NewReader(data)
	for {
		var sample int16
		err := binary.Read(reader, binary.LittleEndian, &sample)
		switch {
		case err == io.EOF:
			return // 讀取完畢
		case err != nil:
			log.Println("讀取音頻樣本時出錯:", err)
			return
		}
		// 將 int16 轉(zhuǎn)為 int 并追加到緩沖區(qū)
		buffer.Data = append(buffer.Data, int(sample))
	}
}

小提醒(認(rèn)真臉)

  • 代碼中為了簡潔,忽略了大部分錯誤處理。實際項目中請務(wù)必加上!
  • 錄音需要麥克風(fēng)權(quán)限,Windows 可能會彈出隱私提示。
  • 如果你錄下了什么不可描述的內(nèi)容……后果自負(fù),本人概不負(fù)責(zé)

結(jié)語

用 Go 在 Windows 上錄音,聽起來是不是有點(diǎn)"跨界"?但正是這種混搭,才讓編程充滿樂趣。下次你可以在這個基礎(chǔ)上加個 GUI、自動上傳到云盤,甚至做個"語音日記"小工具。

好了,我去試試錄下我家母老虎打呼的聲音了。你呢?打算錄點(diǎn)啥?

你的聲音,值得被保存——哪怕是吐槽代碼的那一刻。

到此這篇關(guān)于基于Go語言編寫一個能在Windows上錄音的小程序的文章就介紹到這了,更多相關(guān)Go語言實現(xiàn)錄音內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go語言設(shè)計實現(xiàn)在任務(wù)欄里提醒你喝水的兔子

    Go語言設(shè)計實現(xiàn)在任務(wù)欄里提醒你喝水的兔子

    這篇文章主要為大家介紹了Go語言設(shè)計實現(xiàn)在任務(wù)欄里提醒你喝水的兔子示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • Gin框架中的路由與請求處理的實現(xiàn)

    Gin框架中的路由與請求處理的實現(xiàn)

    本文主要介紹了Gin框架中的路由與請求處理的實現(xiàn),包括路徑參數(shù)、查詢參數(shù)和路由分組的使用,具有一定的參考價值,感興趣的可以了解一下
    2025-06-06
  • go開發(fā)alertmanger實現(xiàn)釘釘報警

    go開發(fā)alertmanger實現(xiàn)釘釘報警

    本文主要介紹了go開發(fā)alertmanger實現(xiàn)釘釘報警,通過自己的url實現(xiàn)alertmanager的釘釘報警,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • 完美解決golang go get私有倉庫的問題

    完美解決golang go get私有倉庫的問題

    這篇文章主要介紹了完美解決golang go get私有倉庫的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05
  • 一文帶你掌握Golang Interface原理和使用技巧

    一文帶你掌握Golang Interface原理和使用技巧

    Golang 中的 interface 是一種非常重要的特性,可以讓我們寫出更加靈活的代碼。在本篇文章中,我們將深入探討 Golang 中interface 的原理和使用技巧,感興趣的可以了解一下
    2023-04-04
  • Go strconv包實現(xiàn)字符串與數(shù)值轉(zhuǎn)換的深度解析

    Go strconv包實現(xiàn)字符串與數(shù)值轉(zhuǎn)換的深度解析

    在 Go 語言開發(fā)中,字符串與基本數(shù)據(jù)類型之間的轉(zhuǎn)換非常常見,Go 標(biāo)準(zhǔn)庫中的 strconv 包正是為這些場景設(shè)計的,下面小編就和大家詳細(xì)介紹一下它的具體應(yīng)用吧
    2026-03-03
  • Go中的格式化字符串fmt.Sprintf()和fmt.Printf()使用示例

    Go中的格式化字符串fmt.Sprintf()和fmt.Printf()使用示例

    這篇文章主要為大家介紹了Go中的格式化字符串fmt.Sprintf()和fmt.Printf()使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06
  • golang 整合antlr語法校驗解析

    golang 整合antlr語法校驗解析

    Antlr是一個語法分析器,本身是用java實現(xiàn)的,然是Runtime的庫也支持Golang、Java、Python等,本文給大家講解使用golang整合antlr進(jìn)行語法解析,感興趣的朋友一起看看吧
    2023-02-02
  • golang的序列化與反序列化的幾種方式

    golang的序列化與反序列化的幾種方式

    這篇文章主要介紹了golang的序列化與反序列化的幾種方式,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • Go秒爬博客園100頁新聞

    Go秒爬博客園100頁新聞

    利用go語言的協(xié)程并發(fā)優(yōu)勢爬取網(wǎng)頁速度相當(dāng)之快,博客園100頁新聞標(biāo)題只需一秒即可全部爬取,跟著小編一起去看看如何實現(xiàn)的,希望大家可以從中受益
    2018-09-09

最新評論

曲沃县| 长子县| 阜新市| 东辽县| 大关县| 郁南县| 富阳市| 涿州市| 元谋县| 新乡市| 伊宁县| 日土县| 宁乡县| 大新县| 荃湾区| 云南省| 宜兰县| 盱眙县| 九江县| 健康| 合山市| 通化县| 特克斯县| 宁海县| 辉县市| 望奎县| 三明市| 榆社县| 定兴县| 苏尼特左旗| 贵港市| 额济纳旗| 阿克陶县| 靖州| 宾川县| 怀宁县| 满洲里市| 鸡东县| 桂林市| 黑山县| 常熟市|