diff --git a/JianGongYun/JianGongYun.csproj b/JianGongYun/JianGongYun.csproj
index 55aa31d..f189d0c 100644
--- a/JianGongYun/JianGongYun.csproj
+++ b/JianGongYun/JianGongYun.csproj
@@ -56,6 +56,6 @@
-
+
diff --git a/JianGongYun/TRTC/Components/TXLiteAVVideoView.cs b/JianGongYun/TRTC/Components/TXLiteAVVideoView.cs
index c2d7000..e2c5275 100644
--- a/JianGongYun/TRTC/Components/TXLiteAVVideoView.cs
+++ b/JianGongYun/TRTC/Components/TXLiteAVVideoView.cs
@@ -163,6 +163,9 @@ namespace JianGongYun.TRTC.Components
{
if (!mFirstFrame)
mFirstFrame = true;
+
+ OnRenderVideoFrameHandler?.Invoke(data, width, height);
+
if (mPause)
return false;
if (data == null || data.Length <= 0)
@@ -237,7 +240,6 @@ namespace JianGongYun.TRTC.Components
private void RenderFillMode(DrawingContext dc, byte[] data, int width, int height, int rotation)
{
- OnRenderVideoFrameHandler?.Invoke(data, width, height);
int viewWidth = (int)this.ActualWidth, viewHeight = (int)this.ActualHeight;
PixelFormat pixelFormat = PixelFormats.Pbgra32;
int bytesPerPixel = (pixelFormat.BitsPerPixel + 7) / 8;
@@ -271,7 +273,6 @@ namespace JianGongYun.TRTC.Components
private void RenderFitMode(DrawingContext dc, byte[] data, int width, int height, int rotation)
{
- OnRenderVideoFrameHandler?.Invoke(data, width, height);
int viewWidth = (int)this.ActualWidth, viewHeight = (int)this.ActualHeight;
PixelFormat pixelFormat = PixelFormats.Pbgra32;
int bytesPerPixel = (pixelFormat.BitsPerPixel + 7) / 8;
diff --git a/JianGongYun/TRTC/LiveClassroom.cs b/JianGongYun/TRTC/LiveClassroom.cs
index 2bc38f4..6b610de 100644
--- a/JianGongYun/TRTC/LiveClassroom.cs
+++ b/JianGongYun/TRTC/LiveClassroom.cs
@@ -99,7 +99,6 @@ namespace JianGongYun.TRTC
if (!string.IsNullOrEmpty(currentMic))
{
var res = lTXDeviceManager.setCurrentDevice(TRTCDeviceType.TXMediaDeviceTypeMic, currentMic);
- Console.WriteLine($"设置麦克风:{res}");
}
lTXDeviceManager.setCurrentDeviceVolume(TRTCDeviceType.TXMediaDeviceTypeMic, settingWindowViewModel.MicVolume);//麦克风采集音量
lTRTCCloud.setSystemAudioLoopbackVolume(settingWindowViewModel.SytemGatherVolume);//系统声音采集音量
@@ -165,11 +164,8 @@ namespace JianGongYun.TRTC
var view = AddCustomVideoView(parent, CurrentClassroomEntity.TeacherId, TRTCVideoStreamType.TRTCVideoStreamTypeBig, true);
if (liveWinMode.IsLive)
{
- //Stopwatch sw = new Stopwatch();
- //VideoRecordTask(view, TRTCVideoStreamType.TRTCVideoStreamTypeBig);
view.OnRenderVideoFrameHandler += (data, w, h) =>
{
- //sw.Restart();
lock (MainFrame)
{
if (MainFrame.Cols != w || MainFrame.Rows != h)
@@ -178,8 +174,6 @@ namespace JianGongYun.TRTC
}
Marshal.Copy(data, 0, MainFrame.Data, data.Length);
}
- //sw.Stop();
- //Debug.Print("main" + sw.ElapsedMilliseconds.ToString());
};
}
return view;
@@ -221,11 +215,8 @@ namespace JianGongYun.TRTC
var view = AddCustomVideoView(parent, CurrentClassroomEntity.TeacherId, TRTCVideoStreamType.TRTCVideoStreamTypeSub, true);
if (liveWinMode.IsLive)
{
- //Stopwatch sw = new Stopwatch();
- //VideoRecordTask(view, TRTCVideoStreamType.TRTCVideoStreamTypeSub);
view.OnRenderVideoFrameHandler += (data, w, h) =>
{
- //sw.Restart();
lock (SubFrame)
{
if (SubFrame.Cols != w || SubFrame.Rows != h)
@@ -234,8 +225,6 @@ namespace JianGongYun.TRTC
}
Marshal.Copy(data, 0, SubFrame.Data, data.Length);
}
- //sw.Stop();
- //Debug.Print("sub" + sw.ElapsedMilliseconds.ToString());
};
}
return view;
@@ -280,25 +269,27 @@ namespace JianGongYun.TRTC
{
liveWinMode.MicRunning = true;
lTRTCCloud.startLocalAudio(settingWindowViewModel.LiveAudioLevel);
- //if (liveWinMode.IsLive && !liveWinMode.AudioRecordRunning)
- //{
- // liveWinMode.AudioRecordRunning = true;
- // //var time = Util.TimeStr();
- // var pars = new TRTCAudioRecordingParams { filePath = Path.Combine(RecoderDir, $"temp_audio.aac") };
- // var res = lTRTCCloud.startAudioRecording(ref pars);
- // //Console.WriteLine(res);
- //}
+ StartRecordAudio();
}
}
+ ///
+ /// 录音
+ ///
public static void StartRecordAudio()
{
if (liveWinMode.IsLive && !liveWinMode.AudioRecordRunning)
{
liveWinMode.AudioRecordRunning = true;
- //var time = Util.TimeStr();
var pars = new TRTCAudioRecordingParams { filePath = Path.Combine(RecoderDir, $"temp_audio.aac") };
- var res = lTRTCCloud.startAudioRecording(ref pars);
- //Console.WriteLine(res);
+ lTRTCCloud.startAudioRecording(ref pars);
+ }
+ }
+ public static void StopRecordAudio()
+ {
+ if (liveWinMode.AudioRecordRunning)
+ {
+ liveWinMode.AudioRecordRunning = false;
+ lTRTCCloud.stopAudioRecording();
}
}
///
@@ -309,11 +300,7 @@ namespace JianGongYun.TRTC
if (liveWinMode.MicRunning)
{
liveWinMode.MicRunning = false;
- if (liveWinMode.AudioRecordRunning)
- {
- liveWinMode.AudioRecordRunning = false;
- lTRTCCloud.stopAudioRecording();
- }
+ StopRecordAudio();
lTRTCCloud.stopLocalAudio();
}
}
@@ -337,31 +324,41 @@ namespace JianGongYun.TRTC
var fps = settingWindowViewModel.LiveFps;//视频采集的fps
BackgroundFrame = new Mat(int.Parse(resolution[2]), int.Parse(resolution[1]), MatType.CV_8UC4, backColor);//合成双路视频的背景
var delay = 1000 / (int)fps;//每帧时间
- var delayEqualize = 0;//每帧时间补偿,在性能和其他因素影响下delay的时间不一定充足
var _recoderDir = RecoderDir;
var videoFile = Path.Combine(_recoderDir, $"temp_video.avi");
//var videoFrameTemp = Path.Combine(_recoderDir, $"videoFrameTemp.bmp");
var backHeight = BackgroundFrame.Rows;//画面高度
var backWidth = BackgroundFrame.Cols;//画面宽度
- VideoWriter vw = new VideoWriter(videoFile, FourCC.H264, fps, BackgroundFrame.Size());
+
var end = false;
+
+
+ ConcurrentQueue mats = new ConcurrentQueue();
+
+ //int runFps = 0;//实时帧
+ //Timer timer = new Timer((a) =>
+ //{
+ // Debug.Print($"runFps {runFps}. leavingsMat {mats.Count}.");
+ // Interlocked.Exchange(ref runFps, 0);
+ //}, null, 0, 1000);
+
onEnd = () =>
{
end = true;
+ //timer.Dispose();
};
-
-
-
+ //帧合并线程
Task.Factory.StartNew(() =>
{
- Stopwatch stopwatch = new Stopwatch();//计时器
+ Stopwatch stopwatch = new Stopwatch();//计时器
bool onlyCameraInit = false;//只有摄像头的话背景填充为backColor,变量标记只需设置一次
bool noImgInit = false;//没有画面背景也填充backColor,变量标记只需设置一次
+ var delayEqualize = 0;//每帧时间补偿,在性能和其他因素影响下delay的时间不一定充足
//屏幕分享画面
var screenRoi = BackgroundFrame[new OpenCvSharp.Rect(0, 0, backWidth, backHeight)];
@@ -376,7 +373,10 @@ namespace JianGongYun.TRTC
//摄像头大画面位置
var bigRoi = BackgroundFrame[new OpenCvSharp.Rect((backWidth - backHeight) / 2, 0, backHeight, backHeight)];
- StartRecordAudio();
+
+
+
+ Debug.Print("开始处理帧线程");
while (!end)
{
stopwatch.Restart();
@@ -422,7 +422,7 @@ namespace JianGongYun.TRTC
}
}
- Skip1:
+ Skip1:
if (liveWinMode.CameraRunning)//摄像头分享中
{
@@ -450,40 +450,91 @@ namespace JianGongYun.TRTC
}
}
- Skip2:
+ Skip2:
- var temp = BackgroundFrame.CvtColor(ColorConversionCodes.BGRA2BGR);
- vw.Write(temp);
- temp.Dispose();
+ mats.Enqueue(BackgroundFrame.CvtColor(ColorConversionCodes.BGRA2BGR));
+ //Interlocked.Increment(ref runFps);
stopwatch.Stop();
- var aa = $"video frame run {stopwatch.ElapsedMilliseconds}";
- //Debug.Print(aa);
- Console.WriteLine(aa);
var sleep = delay - (int)stopwatch.ElapsedMilliseconds;//每帧时间减去每帧处理时间为sleep时间
- if (sleep < 0)//如果处理时间超过了每帧时间,记录下来
+ //if (sleep < 0)//如果处理时间超过了每帧时间,记录下来
+ //{
+ // delayEqualize += sleep;
+ //}
+ //if (delayEqualize < 0 && sleep > 0)
+ //{
+ // delayEqualize += sleep;
+ // if (delayEqualize > 0)
+ // {
+ // delayEqualize = 0;
+ // }
+ //}
+ //var lastsleep = sleep + delayEqualize;//理论休眠时间再去掉补偿时间
+ //Debug.Print($"video frame run {stopwatch.ElapsedMilliseconds}. lastsleep {lastsleep}. sum {(stopwatch.ElapsedMilliseconds + lastsleep)}");
+ //if (lastsleep > 0)
+ //{
+ // Thread.Sleep(lastsleep);
+ //}
+ if (liveWinMode.IsLive && sleep > 0)
{
- delayEqualize += sleep;
- }
- if (delayEqualize < 0 && sleep > 0)
- {
- delayEqualize += sleep;
- if (delayEqualize > 0)
- {
- delayEqualize = 0;
- }
- }
- var lastsleep = sleep + delayEqualize;//理论休眠时间再去掉补偿时间
- if (lastsleep > 0)
- {
- Thread.Sleep(lastsleep);
+ Thread.Sleep(sleep);
}
}
BackgroundFrame?.Dispose();
BackgroundFrame = null;
- vw.Dispose();
- Debug.Print("录制结束");
+ Debug.Print("结束处理帧线程");
}, TaskCreationOptions.LongRunning);//新开线程
+ //新开线程写文件,减少帧处理时间
+ Task.Factory.StartNew(() =>
+ {
+ var delayEqualize = 0;//每帧时间补偿,在性能和其他因素影响下delay的时间不一定充足
+ VideoWriter vw = new VideoWriter(videoFile, FourCC.H264, fps, BackgroundFrame.Size());
+ Stopwatch stopwatch = new Stopwatch();//计时器
+ Debug.Print("开始写入视频线程");
+ while (!end || mats.Count > 0)
+ {
+ if (mats.Count > 0)
+ {
+ if (mats.TryDequeue(out var frame))
+ {
+ stopwatch.Restart();
+ vw.Write(frame);
+ frame.Dispose();
+ stopwatch.Stop();
+ Debug.Print($"video frame write {stopwatch.ElapsedMilliseconds}");
+ //var sleep = delay - (int)stopwatch.ElapsedMilliseconds;//每帧时间减去每帧处理时间为sleep时间
+ //if (sleep < 0)//如果处理时间超过了每帧时间,记录下来
+ //{
+ // delayEqualize += sleep;
+ //}
+ //if (delayEqualize < 0 && sleep > 0)
+ //{
+ // delayEqualize += sleep;
+ // if (delayEqualize > 0)
+ // {
+ // delayEqualize = 0;
+ // }
+ //}
+ //var lastsleep = sleep + delayEqualize;//理论休眠时间再去掉补偿时间
+ //if (lastsleep > 0)
+ //{
+ // Thread.Sleep(lastsleep);
+ //}
+ }
+ else
+ {
+ Thread.Sleep(delay);
+ }
+ }
+ else
+ {
+ Thread.Sleep(delay);
+ }
+ }
+ vw.Dispose();
+ Debug.Print("结束写入视频线程");
+ }, TaskCreationOptions.LongRunning);
+
}
///
diff --git a/JianGongYun/TRTC/Windows/LiveWindow.xaml.cs b/JianGongYun/TRTC/Windows/LiveWindow.xaml.cs
index d4c7243..032a938 100644
--- a/JianGongYun/TRTC/Windows/LiveWindow.xaml.cs
+++ b/JianGongYun/TRTC/Windows/LiveWindow.xaml.cs
@@ -52,14 +52,14 @@ namespace JianGongYun.TRTC.Windows
Rad2.Foreground = color;
Rad3.Foreground = color;
Rad4.Foreground = color;
- //LiveClassroom.PauseAllView(false);//切前台启动实时预览渲染
+ LiveClassroom.PauseAllView(false);//切前台启动实时预览渲染
}
protected override void OnDeactivated(EventArgs e)
{
base.OnDeactivated(e);
- //LiveClassroom.PauseAllView(true);//切后台停止实时预览渲染
+ LiveClassroom.PauseAllView(true);//切后台停止实时预览渲染
}
private Window settingWindow;
diff --git a/JianGongYun/TRTC/Windows/SettingWindow.xaml b/JianGongYun/TRTC/Windows/SettingWindow.xaml
index bf4a294..d0a287c 100644
--- a/JianGongYun/TRTC/Windows/SettingWindow.xaml
+++ b/JianGongYun/TRTC/Windows/SettingWindow.xaml
@@ -103,6 +103,7 @@
录制倒计时
+
@@ -136,8 +137,8 @@
帧率(fps)
-
-
+
diff --git a/JianGongYun/TRTC_SDK/Win32/lib/ffmpeg.exe b/JianGongYun/TRTC_SDK/Win32/lib/ffmpeg.exe
new file mode 100644
index 0000000..8df69e8
Binary files /dev/null and b/JianGongYun/TRTC_SDK/Win32/lib/ffmpeg.exe differ
diff --git a/JianGongYun/TRTC_SDK/Win64/lib/ffmpeg.exe b/JianGongYun/TRTC_SDK/Win64/lib/ffmpeg.exe
new file mode 100644
index 0000000..bbd81aa
Binary files /dev/null and b/JianGongYun/TRTC_SDK/Win64/lib/ffmpeg.exe differ