关于API函数Mixeropen的用法

ltolll 2002-08-03 11:17:38
API函数Mixeropen的各个参数的作用,有例子程序就更好了。
...全文
816 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
ltolll 2002-08-05
  • 打赏
  • 举报
回复
感谢zpointroc(横空逆云)的回答,但我仍有一些问题(关于mixeropen),而且您的例子对我来说太复杂,我会另开贴讨论此问题,欢迎继续帮忙。此贴结了。再次感谢。
zpointroc 2002-08-04
  • 打赏
  • 举报
回复
下面是例子:(第一部分)

'这个程序需要建立一个模块,一个窗体
'窗体中必须有两个Label,两个ProgressBar,一个时间控件和一个CheckBox

'粘贴以下代码到窗体文件
Dim hmixer As Long ' mixer handle
Dim inputVolCtrl As MIXERCONTROL ' waveout volume control
Dim outputVolCtrl As MIXERCONTROL ' microphone volume control
Dim rc As Long ' return code
Dim ok As Boolean ' boolean return code

Dim mxcd As MIXERCONTROLDETAILS ' control info
Dim vol As MIXERCONTROLDETAILS_SIGNED ' control's signed value
Dim volume As Long ' volume value
Dim volHmem As Long ' handle to volume memory
Private Sub Form_Load()
Me.ScaleMode = vbTwips
Me.Caption = "Volume meter"
Label1.Move 0, 0
Label1.AutoSize = True
Label1.Caption = "Input level"
Label2.Move 0, 4 * Label1.Height
Label2.AutoSize = True
Label2.Caption = "Output level"
ProgressBar1.Move Label1.Width * 2, 0, 3375
ProgressBar2.Move Label1.Width * 2, Label2.Top, 3375
Check1.Move ProgressBar1.Left, ProgressBar1.Height
Check1.Caption = "Get Input"
Me.Move Me.Left, Me.Top, ProgressBar1.Width + ProgressBar1.Left + 10 * Screen.TwipsPerPixelX, ProgressBar2.Top + ProgressBar2.Height + 30 * Screen.TwipsPerPixelY
Timer1.Interval = 50
Timer1.Enabled = True

' Open the mixer specified by DEVICEID
rc = mixerOpen(hmixer, DEVICEID, 0, 0, 0)

If ((MMSYSERR_NOERROR <> rc)) Then
MsgBox "Couldn't open the mixer."
Exit Sub
End If

' Get the input volume meter
ok = GetControl(hmixer, MIXERLINE_COMPONENTTYPE_DST_WAVEIN, MIXERCONTROL_CONTROLTYPE_PEAKMETER, inputVolCtrl)

If (ok <> True) Then
ok = GetControl(hmixer, MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE, MIXERCONTROL_CONTROLTYPE_PEAKMETER, inputVolCtrl)
End If

If (ok = True) Then
ProgressBar1.Min = 0
ProgressBar1.Max = inputVolCtrl.lMaximum
Else
ProgressBar1.Enabled = False
MsgBox "Couldn't get wavein meter"
End If

' Get the output volume meter
ok = GetControl(hmixer, MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT, MIXERCONTROL_CONTROLTYPE_PEAKMETER, outputVolCtrl)

If (ok = True) Then
ProgressBar2.Min = 0
ProgressBar2.Max = outputVolCtrl.lMaximum
Else
ProgressBar2.Enabled = False
MsgBox "Couldn't get waveout meter"
End If

' Initialize mixercontrol structure
mxcd.cbStruct = Len(mxcd)
volHmem = GlobalAlloc(&H0, Len(volume)) ' Allocate a buffer for the volume value
mxcd.paDetails = GlobalLock(volHmem)
mxcd.cbDetails = Len(volume)
mxcd.cChannels = 1

End Sub
Private Sub Check1_Click()
If (Check1.Value = 1) Then
StartInput ' Start receiving audio input
Else
StopInput ' Stop receiving audio input
End If
End Sub
Private Sub Timer1_Timer()

On Error Resume Next

' Process sound buffer if recording
If (fRecording) Then
For i = 0 To (NUM_BUFFERS - 1)
If inHdr(i).dwFlags And WHDR_DONE Then
rc = waveInAddBuffer(hWaveIn, inHdr(i), Len(inHdr(i)))
End If
Next
End If

' Get the current input level
If (ProgressBar1.Enabled = True) Then
mxcd.dwControlID = inputVolCtrl.dwControlID
mxcd.item = inputVolCtrl.cMultipleItems
rc = mixerGetControlDetails(hmixer, mxcd, MIXER_GETCONTROLDETAILSF_VALUE)
CopyStructFromPtr volume, mxcd.paDetails, Len(volume)
If (volume < 0) Then
volume = -volume
End If
ProgressBar1.Value = volume
End If

' Get the current output level
If (ProgressBar2.Enabled = True) Then
mxcd.dwControlID = outputVolCtrl.dwControlID
mxcd.item = outputVolCtrl.cMultipleItems
rc = mixerGetControlDetails(hmixer, mxcd, MIXER_GETCONTROLDETAILSF_VALUE)
CopyStructFromPtr volume, mxcd.paDetails, Len(volume)

If (volume < 0) Then volume = -volume

ProgressBar2.Value = volume
End If
End Sub
Private Sub Form_Unload(Cancel As Integer)
If (fRecording = True) Then
StopInput
End If
GlobalFree volHmem
End Sub
zpointroc 2002-08-04
  • 打赏
  • 举报
回复
Mixeropen

声明:
Private Declare Function mixerOpen Lib "winmm.dll" Alias "mixerOpen" (phmx As Long, ByVal uMxId As Long, ByVal dwCallback As Long, ByVal dwInstance As Long, ByVal fdwOpen As Long) As Long
参数:
?phmx
Address of a variable that will receive a handle identifying the opened mixer device. Use this handle to identify the device when calling other audio mixer functions. This parameter cannot be NULL.

?uMxId
Identifier of the mixer device to open. Use a valid device identifier or any HMIXEROBJ (see the mixerGetID function for a description of mixer object handles). A 搈apper?for audio mixer devices does not currently exist, so a mixer device identifier of - 1 is not valid.

?dwCallback
Handle of a window called when the state of an audio line and/or control associated with the device being opened is changed. Specify zero for this parameter if no callback mechanism is to be used.

?dwInstance
User instance data passed to the callback function. This parameter is not used with window callback functions.

?fdwOpen
Flags for opening the device. The following values are defined:
CALLBACK_WINDOW
The dwCallback parameter is assumed to be a window handle.
MIXER_OBJECTF_AUX
The uMxId parameter is an auxiliary device identifier in the range of zero to one less than the number of devices returned by the auxGetNumDevs function.
MIXER_OBJECTF_HMIDIIN
The uMxId parameter is the handle of a MIDI input device. This handle must have been returned by the midiInOpen function.
MIXER_OBJECTF_HMIDIOUT
The uMxId parameter is the handle of a MIDI output device. This handle must have been returned by the midiOutOpen function.
MIXER_OBJECTF_HMIXER
The uMxId parameter is a mixer device handle returned by the mixerOpen function. This flag is optional.
MIXER_OBJECTF_HWAVEIN
The uMxId parameter is a waveform-audio input handle returned by the waveInOpen function.
MIXER_OBJECTF_HWAVEOUT
The uMxId parameter is a waveform-audio output handle returned by the waveOutOpen function.
MIXER_OBJECTF_MIDIIN
The uMxId parameter is the identifier of a MIDI input device. This identifier must be in the range of zero to one less than the number of devices returned by the midiInGetNumDevs function.
MIXER_OBJECTF_MIDIOUT
The uMxId parameter is the identifier of a MIDI output device. This identifier must be in the range of zero to one less than the number of devices returned by the midiOutGetNumDevs function.
MIXER_OBJECTF_MIXER
The uMxId parameter is a mixer device identifier in the range of zero to one less than the number of devices returned by the mixerGetNumDevs function. This flag is optional.
MIXER_OBJECTF_WAVEIN
The uMxId parameter is the identifier of a waveform-audio input device in the range of zero to one less than the number of devices returned by the waveInGetNumDevs function.
MIXER_OBJECTF_WAVEOUT
The uMxId parameter is the identifier of a waveform-audio output device in the range of zero to one less than the number of devices returned by the waveOutGetNumDevs function.

返回值:
Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following:
MMSYSERR_ALLOCATED
The specified resource is already allocated by the maximum number of clients possible.

MMSYSERR_BADDEVICEID
The uMxId parameter specifies an invalid device identifier.

MMSYSERR_INVALFLAG
One or more flags are invalid.

MMSYSERR_INVALHANDLE
The uMxId parameter specifies an invalid handle.

MMSYSERR_INVALPARAM
One or more parameters are invalid.

MMSYSERR_NODRIVER
No mixer device is available for the object specified by uMxId. Note that the location referenced by uMxId will also contain the value - 1.

MMSYSERR_NOMEM
Unable to allocate resources.
zpointroc 2002-08-04
  • 打赏
  • 举报
回复
1.format函数的问题我没有遇到。是不是代码不全的原因
很明显DiskSpace = format$(DiskSpace, "###,###")
中,DiskSpace应该是一个Long型的数据,而Format$函数返回值是字串型
所以会出现错误
2.Mixer是指混音器
混音器的结构:混音器由多个destination(目的单元)组成,如Playback(回放)、Recording(录音)、Voice command(语音命令)等等。 而每个destination又由多个Connections(连接设备), 如回放下有CD Audio、MIDI 、Wave等等。每条 Connection 联系着一个或以上的Control(控制器)。Control是混音器的关键,有Volume Control(音量控制器)、Mute Control(静音控制器)、Meter Control(仪表控制器)等等
3.ProgressBar这个控件在MicroSoft Windows Common Controls 6.0(sp4)中
"mscomctl.ocx"
4:这里有个源代码,你看看吧
http://download1.ccidnet.com/source_code/vb/2165_Cd%20Player.zip
zpointroc 2002-08-04
  • 打赏
  • 举报
回复
'昨天说了,程序没有完,因为一个人在一个帖子中不能连续发言超过三次
'第三部分(粘贴到模块)
Function GetControl(ByVal hmixer As Long, ByVal componentType As Long, ByVal ctrlType As Long, ByRef mxc As MIXERCONTROL) As Boolean
' This function attempts to obtain a mixer control. Returns True if successful.

Dim mxlc As MIXERLINECONTROLS
Dim mxl As MIXERLINE
Dim hmem As Long
Dim rc As Long

mxl.cbStruct = Len(mxl)
mxl.dwComponentType = componentType

' Obtain a line corresponding to the component type
rc = mixerGetLineInfo(hmixer, mxl, MIXER_GETLINEINFOF_COMPONENTTYPE)

If (MMSYSERR_NOERROR = rc) Then
mxlc.cbStruct = Len(mxlc)
mxlc.dwLineID = mxl.dwLineID
mxlc.dwControl = ctrlType
mxlc.cControls = 1
mxlc.cbmxctrl = Len(mxc)

' Allocate a buffer for the control
'hmem = GlobalAlloc(&H40, Len(mxc))
hmem = GlobalAlloc(GMEM_FIXED, Len(mxc))
mxlc.pamxctrl = GlobalLock(hmem)
mxc.cbStruct = Len(mxc)

' Get the control
rc = mixerGetLineControls(hmixer, mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE)

If (MMSYSERR_NOERROR = rc) Then
GetControl = True

' Copy the control into the destination structure
CopyStructFromPtr mxc, mxlc.pamxctrl, Len(mxc)
Else
GetControl = False
End If
GlobalFree (hmem)
Exit Function
End If

GetControl = False
End Function
' Function to process the wave recording notifications.
Sub waveInProc(ByVal hwi As Long, ByVal uMsg As Long, ByVal dwInstance As Long, ByRef hdr As WAVEHDR, ByVal dwParam2 As Long)
If (uMsg = MM_WIM_DATA) Then
If fRecording Then
rc = waveInAddBuffer(hwi, hdr, Len(hdr))
End If
End If
End Sub
' This function starts recording from the soundcard. The soundcard must be recording in order to
' monitor the input level. Without starting the recording from this application, input level
' can still be monitored if another application is recording audio
Function StartInput() As Boolean

If fRecording Then
StartInput = True
Exit Function
End If

format.wFormatTag = 1
format.nChannels = 1
format.wBitsPerSample = 8
format.nSamplesPerSec = 8000
format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8
format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign
format.cbSize = 0

For i = 0 To NUM_BUFFERS - 1
hmem(i) = GlobalAlloc(&H40, BUFFER_SIZE)
inHdr(i).lpData = GlobalLock(hmem(i))
inHdr(i).dwBufferLength = BUFFER_SIZE
inHdr(i).dwFlags = 0
inHdr(i).dwLoops = 0
Next

rc = waveInOpen(hWaveIn, DEVICEID, format, 0, 0, 0)
If rc <> 0 Then
waveInGetErrorText rc, msg, Len(msg)
MsgBox msg
StartInput = False
Exit Function
End If

For i = 0 To NUM_BUFFERS - 1
rc = waveInPrepareHeader(hWaveIn, inHdr(i), Len(inHdr(i)))
If (rc <> 0) Then
waveInGetErrorText rc, msg, Len(msg)
MsgBox msg
End If
Next

For i = 0 To NUM_BUFFERS - 1
rc = waveInAddBuffer(hWaveIn, inHdr(i), Len(inHdr(i)))
If (rc <> 0) Then
waveInGetErrorText rc, msg, Len(msg)
MsgBox msg
End If
Next

fRecording = True
rc = waveInStart(hWaveIn)
StartInput = True
End Function
' Stop receiving audio input on the soundcard
Sub StopInput()

fRecording = False
waveInReset hWaveIn
waveInStop hWaveIn
For i = 0 To NUM_BUFFERS - 1
waveInUnprepareHeader hWaveIn, inHdr(i), Len(inHdr(i))
GlobalFree hmem(i)
Next
waveInClose hWaveIn
End Sub
ltolll 2002-08-04
  • 打赏
  • 举报
回复
感谢“横空逆云”
但有几个问题,
1、在例子程序执行时在
“DiskSpace = format$(DiskSpace, "###,###")
'以规定格式显示,如732,324,231”
行出现编译错误:“类型—声明字符与声明的数据类型不符合。”其中format$被选中。不知什么意思
2、您关于mixeropen函数的英文说明我在MSDN里也程看过,但由于我的E文很差所以有很多地方不明白。比如第一个参数phmx是说“它是一个指定的地址值,用它来指定一个已打开的mixer设备的句柄,用这个句柄在调用其它音频mixer 设备时来标识指定的设备。“这里的mixer设备指的是什么?系统里为什么存在多个mixer(或者说都存在哪些mixer),音频mixer与mixer有何区别?
3、ProgressBar这个控件应该怎么引用?(我找了好久也没找到)
zpointroc 2002-08-04
  • 打赏
  • 举报
回复
第二部分
'粘贴以下代码到模块文件
Public Const CALLBACK_FUNCTION = &H30000
Public Const MM_WIM_DATA = &H3C0
Public Const WHDR_DONE = &H1 ' done bit
Public Const GMEM_FIXED = &H0 ' Global Memory Flag used by GlobalAlloc functin

Type WAVEHDR
lpData As Long
dwBufferLength As Long
dwBytesRecorded As Long
dwUser As Long
dwFlags As Long
dwLoops As Long
lpNext As Long
Reserved As Long
End Type
Type WAVEINCAPS
wMid As Integer
wPid As Integer
vDriverVersion As Long
szPname As String * 32
dwFormats As Long
wChannels As Integer
End Type
Type WAVEFORMAT
wFormatTag As Integer
nChannels As Integer
nSamplesPerSec As Long
nAvgBytesPerSec As Long
nBlockAlign As Integer
wBitsPerSample As Integer
cbSize As Integer
End Type

Declare Function waveInOpen Lib "winmm.dll" (lphWaveIn As Long, ByVal uDeviceID As Long, lpFormat As WAVEFORMAT, ByVal dwCallback As Long, ByVal dwInstance As Long, ByVal dwFlags As Long) As Long
Declare Function waveInPrepareHeader Lib "winmm.dll" (ByVal hWaveIn As Long, lpWaveInHdr As WAVEHDR, ByVal uSize As Long) As Long
Declare Function waveInReset Lib "winmm.dll" (ByVal hWaveIn As Long) As Long
Declare Function waveInStart Lib "winmm.dll" (ByVal hWaveIn As Long) As Long
Declare Function waveInStop Lib "winmm.dll" (ByVal hWaveIn As Long) As Long
Declare Function waveInUnprepareHeader Lib "winmm.dll" (ByVal hWaveIn As Long, lpWaveInHdr As WAVEHDR, ByVal uSize As Long) As Long
Declare Function waveInClose Lib "winmm.dll" (ByVal hWaveIn As Long) As Long
Declare Function waveInGetDevCaps Lib "winmm.dll" Alias "waveInGetDevCapsA" (ByVal uDeviceID As Long, lpCaps As WAVEINCAPS, ByVal uSize As Long) As Long
Declare Function waveInGetNumDevs Lib "winmm.dll" () As Long
Declare Function waveInGetErrorText Lib "winmm.dll" Alias "waveInGetErrorTextA" (ByVal err As Long, ByVal lpText As String, ByVal uSize As Long) As Long
Declare Function waveInAddBuffer Lib "winmm.dll" (ByVal hWaveIn As Long, lpWaveInHdr As WAVEHDR, ByVal uSize As Long) As Long

Public Const MMSYSERR_NOERROR = 0
Public Const MAXPNAMELEN = 32

Public Const MIXER_LONG_NAME_CHARS = 64
Public Const MIXER_SHORT_NAME_CHARS = 16
Public Const MIXER_GETLINEINFOF_COMPONENTTYPE = &H3&
Public Const MIXER_GETCONTROLDETAILSF_VALUE = &H0&
Public Const MIXER_GETLINECONTROLSF_ONEBYTYPE = &H2&

Public Const MIXERLINE_COMPONENTTYPE_DST_FIRST = &H0&
Public Const MIXERLINE_COMPONENTTYPE_SRC_FIRST = &H1000&
Public Const MIXERLINE_COMPONENTTYPE_DST_SPEAKERS = (MIXERLINE_COMPONENTTYPE_DST_FIRST + 4)
Public Const MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE = (MIXERLINE_COMPONENTTYPE_SRC_FIRST + 3)
Public Const MIXERLINE_COMPONENTTYPE_SRC_LINE = (MIXERLINE_COMPONENTTYPE_SRC_FIRST + 2)

Public Const MIXERCONTROL_CT_CLASS_FADER = &H50000000
Public Const MIXERCONTROL_CT_UNITS_UNSIGNED = &H30000
Public Const MIXERCONTROL_CT_UNITS_SIGNED = &H20000
Public Const MIXERCONTROL_CT_CLASS_METER = &H10000000
Public Const MIXERCONTROL_CT_SC_METER_POLLED = &H0&
Public Const MIXERCONTROL_CONTROLTYPE_FADER = (MIXERCONTROL_CT_CLASS_FADER Or MIXERCONTROL_CT_UNITS_UNSIGNED)
Public Const MIXERCONTROL_CONTROLTYPE_VOLUME = (MIXERCONTROL_CONTROLTYPE_FADER + 1)
Public Const MIXERLINE_COMPONENTTYPE_DST_WAVEIN = (MIXERLINE_COMPONENTTYPE_DST_FIRST + 7)
Public Const MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT = (MIXERLINE_COMPONENTTYPE_SRC_FIRST + 8)
Public Const MIXERCONTROL_CONTROLTYPE_SIGNEDMETER = (MIXERCONTROL_CT_CLASS_METER Or MIXERCONTROL_CT_SC_METER_POLLED Or MIXERCONTROL_CT_UNITS_SIGNED)
Public Const MIXERCONTROL_CONTROLTYPE_PEAKMETER = (MIXERCONTROL_CONTROLTYPE_SIGNEDMETER + 1)

Declare Function mixerClose Lib "winmm.dll" (ByVal hmx As Long) As Long
Declare Function mixerGetControlDetails Lib "winmm.dll" Alias "mixerGetControlDetailsA" (ByVal hmxobj As Long, pmxcd As MIXERCONTROLDETAILS, ByVal fdwDetails As Long) As Long
Declare Function mixerGetDevCaps Lib "winmm.dll" Alias "mixerGetDevCapsA" (ByVal uMxId As Long, ByVal pmxcaps As MIXERCAPS, ByVal cbmxcaps As Long) As Long
Declare Function mixerGetID Lib "winmm.dll" (ByVal hmxobj As Long, pumxID As Long, ByVal fdwId As Long) As Long
Declare Function mixerGetLineInfo Lib "winmm.dll" Alias "mixerGetLineInfoA" (ByVal hmxobj As Long, pmxl As MIXERLINE, ByVal fdwInfo As Long) As Long
Declare Function mixerGetLineControls Lib "winmm.dll" Alias "mixerGetLineControlsA" (ByVal hmxobj As Long, pmxlc As MIXERLINECONTROLS, ByVal fdwControls As Long) As Long
Declare Function mixerGetNumDevs Lib "winmm.dll" () As Long
Declare Function mixerMessage Lib "winmm.dll" (ByVal hmx As Long, ByVal uMsg As Long, ByVal dwParam1 As Long, ByVal dwParam2 As Long) As Long
Declare Function mixerOpen Lib "winmm.dll" (phmx As Long, ByVal uMxId As Long, ByVal dwCallback As Long, ByVal dwInstance As Long, ByVal fdwOpen As Long) As Long
Declare Function mixerSetControlDetails Lib "winmm.dll" (ByVal hmxobj As Long, pmxcd As MIXERCONTROLDETAILS, ByVal fdwDetails As Long) As Long

Declare Sub CopyStructFromPtr Lib "kernel32" Alias "RtlMoveMemory" (struct As Any, ByVal ptr As Long, ByVal cb As Long)
Declare Sub CopyPtrFromStruct Lib "kernel32" Alias "RtlMoveMemory" (ByVal ptr As Long, struct As Any, ByVal cb As Long)
Declare Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal dwBytes As Long) As Long
Declare Function GlobalLock Lib "kernel32" (ByVal hmem As Long) As Long
Declare Function GlobalFree Lib "kernel32" (ByVal hmem As Long) As Long

Type MIXERCAPS
wMid As Integer
wPid As Integer
vDriverVersion As Long
szPname As String * MAXPNAMELEN
fdwSupport As Long
cDestinations As Long
End Type
Type MIXERCONTROL
cbStruct As Long
dwControlID As Long
dwControlType As Long
fdwControl As Long
cMultipleItems As Long
szShortName As String * MIXER_SHORT_NAME_CHARS
szName As String * MIXER_LONG_NAME_CHARS
lMinimum As Long
lMaximum As Long
Reserved(10) As Long
End Type
Type MIXERCONTROLDETAILS
cbStruct As Long
dwControlID As Long
cChannels As Long
item As Long
cbDetails As Long
paDetails As Long
End Type
Type MIXERCONTROLDETAILS_SIGNED
lValue As Long
End Type
Type MIXERLINE
cbStruct As Long
dwDestination As Long
dwSource As Long
dwLineID As Long
fdwLine As Long
dwUser As Long
dwComponentType As Long
cChannels As Long
cConnections As Long
cControls As Long
szShortName As String * MIXER_SHORT_NAME_CHARS
szName As String * MIXER_LONG_NAME_CHARS
dwType As Long
dwDeviceID As Long
wMid As Integer
wPid As Integer
vDriverVersion As Long
szPname As String * MAXPNAMELEN
End Type
Type MIXERLINECONTROLS
cbStruct As Long
dwLineID As Long
dwControl As Long
cControls As Long
cbmxctrl As Long
pamxctrl As Long
End Type

Public i As Integer, j As Integer, rc As Long, msg As String * 200, hWaveIn As Long
Public Const NUM_BUFFERS = 2
Public format As WAVEFORMAT, hmem(NUM_BUFFERS) As Long, inHdr(NUM_BUFFERS) As WAVEHDR
Public Const BUFFER_SIZE = 8192
Public Const DEVICEID = 0
Public fRecording As Boolean

1,486

社区成员

发帖
与我相关
我的任务
社区描述
VB API
社区管理员
  • API
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧