我是UCMA的新手,我正在通过实例学习。我正在尝试使用以下方案构建2个Lync客户端A和B,
我被困在试图记录B的电话。对于B来电。我需要将audiovideoflow附加到录音机,但我不知道如何做到这一点。我将不胜感激任何帮助。 对未格式化的代码抱歉,我不知道如何正确格式化,我试过了。
感谢。 克里斯
记录来电中收到的媒体。 ***这是我遇到麻烦的部分
使用System; 使用System.Threading; 使用Microsoft.Rtc.Collaboration; 使用Microsoft.Rtc.Collaboration.AudioVideo; 使用Microsoft.Rtc.Signaling; 使用Microsoft.Rtc.Collaboration.Lync;
命名空间Microsoft.Rtc.Collaboration.LyncUAS { 公共类LyncUAS { #region当地人 private LyncUASConfigurationHelper _helper; private UserEndpoint _userEndpoint; private AudioVideoCall _audioVideoCall; private AudioVideoFlow _audioVideoFlow; 私人谈话_incomingConversation;
//Wait handles are only present to keep things synchronous and easy to read.
private AutoResetEvent _autoResetEvent = new AutoResetEvent(false);
private EventHandler<AudioVideoFlowConfigurationRequestedEventArgs> _audioVideoFlowConfigurationRequestedEventHandler;
private EventHandler<MediaFlowStateChangedEventArgs> _audioVideoFlowStateChangedEventHandler;
private AutoResetEvent _waitForAudioVideoCallEstablishCompleted = new AutoResetEvent(false);
private AutoResetEvent _waitForAudioVideoFlowStateChangedToActiveCompleted = new AutoResetEvent(false);
private AutoResetEvent _waitForPrepareSourceCompleted = new AutoResetEvent(false);
#endregion
#region Methods
/// <summary>
/// Instantiate and run the DeclineIncomingCall quickstart.
/// </summary>
/// <param name="args">unused</param>
public static void Main(string[] args)
{
LyncUAS lyncUAS = new LyncUAS();
lyncUAS.Run();
}
private void Run()
{
string filename = "received.wma";
_helper = new LyncUASConfigurationHelper();
// Create a user endpoint, using the network credential object
// defined above.
_userEndpoint = _helper.CreateEstablishedUserEndpoint("Lync UAS" /*endpointFriendlyName*/);
_userEndpoint.RegisterForIncomingCall<AudioVideoCall>(On_AudioVideoCall_Received);
Console.WriteLine("Waiting for incoming call...");
_autoResetEvent.WaitOne();
Console.WriteLine("came after call is connected");
//start recording for audio.
Recorder recorder = new Recorder();
recorder.StateChanged += new EventHandler<RecorderStateChangedEventArgs>(recorder_StateChanged);
recorder.VoiceActivityChanged += new EventHandler<VoiceActivityChangedEventArgs>(recorder_VoiceActivityChanged);
// **********这是问题,目前_audioVideoFlow为null,它没有附加到流 //所以这会失败,如何将_audioVideoFlow附加到来电?帮助!!!
// recorder.AttachFlow(_audioVideoFlow); ------------> HELP!
WmaFileSink sink = new WmaFileSink(filename);
recorder.SetSink(sink);
recorder.Start();
Console.WriteLine("Started Recording ...");
_autoResetEvent.WaitOne();
recorder.Stop();
Console.WriteLine("Stopped Recording ...");
recorder.DetachFlow();
Console.WriteLine("Exiting");
Thread.Sleep(2000);
}
private void audioVideoFlow_StateChanged(object sender, MediaFlowStateChangedEventArgs e)
{
Console.WriteLine("Flow state changed from " + e.PreviousState + " to " + e.State);
//When flow is active, media operations can begin
if (e.State == MediaFlowState.Active)
{
// Flow-related media operations normally begin here.
_waitForAudioVideoFlowStateChangedToActiveCompleted.Set();
}
// call sample event handler
if (_audioVideoFlowStateChangedEventHandler != null)
{
_audioVideoFlowStateChangedEventHandler(sender, e);
}
}
void recorder_VoiceActivityChanged(object sender, VoiceActivityChangedEventArgs e)
{
Console.WriteLine("Recorder detected " + (e.IsVoice ? "voice" : "silence") + " at " + e.TimeStamp);
}
void recorder_StateChanged(object sender, RecorderStateChangedEventArgs e)
{
Console.WriteLine("Recorder state changed from " + e.PreviousState + " to " + e.State);
}
void On_AudioVideoCall_Received(object sender, CallReceivedEventArgs<AudioVideoCall> e)
{
//Type checking was done by the platform; no risk of this being any
// type other than the type expected.
_audioVideoCall = e.Call;
// Call: StateChanged: Only hooked up for logging, to show the call
// state transitions.
_audioVideoCall.StateChanged += new
EventHandler<CallStateChangedEventArgs>(_audioVideoCall_StateChanged);
_incomingConversation = new Conversation(_userEndpoint);
Console.WriteLine("Call Received! From: " + e.RemoteParticipant.Uri + " Toast is: " +e.ToastMessage.Message);
_audioVideoCall.BeginAccept(
ar =>
{
try {
_audioVideoCall.EndAccept(ar);
Console.WriteLine("Call must be connected at this point. "+_audioVideoCall.State);
_autoResetEvent.Set();
} catch (RealTimeException ex) { Console.WriteLine(ex); }
}, null);
}
//Just to record the state transitions in the console.
void _audioVideoCall_StateChanged(object sender, CallStateChangedEventArgs e)
{
Console.WriteLine("Call has changed state. The previous call state was: " + e.PreviousState +
" and the current state is: " + e.State);
if (e.State == CallState.Terminated)
{
Console.WriteLine("Shutting down");
_autoResetEvent.Set();
_helper.ShutdownPlatform();
}
}
#endregion
}
}
答案 0 :(得分:0)
我想我已经弄清楚这里不太正确了。
// Create a user endpoint, using the network credential object
// defined above.
_userEndpoint = _helper.CreateEstablishedUserEndpoint("Lync UAS" /*endpointFriendlyName*/);
_userEndpoint.RegisterForIncomingCall<AudioVideoCall>(On_AudioVideoCall_Received);
Console.WriteLine("Waiting for incoming call...");
_autoResetEvent.WaitOne();
Console.WriteLine("came after call is connected");
//start recording for audio.
Recorder recorder = new Recorder();
recorder.StateChanged += new EventHandler<RecorderStateChangedEventArgs>(recorder_StateChanged);
recorder.VoiceActivityChanged += new EventHandler<VoiceActivityChangedEventArgs>(recorder_VoiceActivityChanged);
//**********This is the issue, currently _audioVideoFlow is null, it is not attached to the flow //So this will fail, how to attach _audioVideoFlow to an incoming call ?? HELP !!!
// recorder.AttachFlow(_audioVideoFlow); ------------> HELP!
到目前为止看起来不错。我假设您正在使用CreateEstablishedUserEndpoint
方法建立等等,但我没有看到您获取_audioVideoFlow值的位置。
我猜你可能会在其他地方这样做,但实际上你遇到问题的可能性很大,这就是:
public static void RegisterForIncomingCall(LocalEndpoint localEndpoint)
{
localEndpoint.RegisterForIncomingCall
<AudioVideoCall>(IncomingCallDelegate);
}
private static void IncomingCallDelegate(object sender, CallReceivedEventArgs<AudioVideoCall> e)
{
e.Call.AudioVideoFlowConfigurationRequested += IncomingCallOnAudioVideoFlowConfigurationRequested;
}
private static void IncomingCallOnAudioVideoFlowConfigurationRequested(object sender, AudioVideoFlowConfigurationRequestedEventArgs e)
{
AudioVideoFlow audioVideoFlow = e.Flow; // <--- There's your flow, gentleman.
}
现在,请拨打RegisterForIncomingCall(_userEndpoint);
,而不是注册来电。
您的AVFlow将在e.Flow上方挂起,然后您可以将其传递到录音机中:recorder.AttachFlow(e.Flow)
或者只是将流程分配到班级中的字段autoResetEvent.WaitOne();
并将其设置在哪里你现在正在设置它。
显然这是一个非常天真的实现。在那几行代码中可能会出现很多问题(异常处理/静态事件处理程序内存泄漏会立即出现);不要忘记连接与会话/呼叫和终端上的状态更改相关的事件,以及任何与恢复相关的项目。