直播完结
This commit is contained in:
parent
fb28b4cc89
commit
4fc0d3bff2
|
@ -19,6 +19,7 @@ using System.Windows.Data;
|
|||
using System.Drawing;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using AduSkin.Controls.Metro;
|
||||
|
||||
namespace JianGongYun.TRTC
|
||||
{
|
||||
|
@ -122,6 +123,37 @@ namespace JianGongYun.TRTC
|
|||
}
|
||||
|
||||
private static string _RecoderDir;
|
||||
|
||||
/// <summary>
|
||||
/// 音频录制文件
|
||||
/// </summary>
|
||||
public static string AudioTempPath
|
||||
{
|
||||
get
|
||||
{
|
||||
return Path.Combine(RecoderDir, $"temp_audio.aac");
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 视频录制文件
|
||||
/// </summary>
|
||||
public static string VideoTempPath
|
||||
{
|
||||
get
|
||||
{
|
||||
return Path.Combine(RecoderDir, $"temp_video.avi");
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 合并后的文件
|
||||
/// </summary>
|
||||
public static string ResultFilePath
|
||||
{
|
||||
get
|
||||
{
|
||||
return Path.Combine(RecoderDir, $"result.avi");
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 录制内容的具体路径
|
||||
/// </summary>
|
||||
|
@ -272,6 +304,7 @@ namespace JianGongYun.TRTC
|
|||
StartRecordAudio();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 录音
|
||||
/// </summary>
|
||||
|
@ -280,7 +313,7 @@ namespace JianGongYun.TRTC
|
|||
if (liveWinMode.IsLive && !liveWinMode.AudioRecordRunning)
|
||||
{
|
||||
liveWinMode.AudioRecordRunning = true;
|
||||
var pars = new TRTCAudioRecordingParams { filePath = Path.Combine(RecoderDir, $"temp_audio.aac") };
|
||||
var pars = new TRTCAudioRecordingParams { filePath = AudioTempPath };
|
||||
lTRTCCloud.startAudioRecording(ref pars);
|
||||
}
|
||||
}
|
||||
|
@ -325,7 +358,6 @@ namespace JianGongYun.TRTC
|
|||
BackgroundFrame = new Mat(int.Parse(resolution[2]), int.Parse(resolution[1]), MatType.CV_8UC4, backColor);//合成双路视频的背景
|
||||
var delay = 1000 / (int)fps;//每帧时间
|
||||
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;//画面宽度
|
||||
|
@ -336,17 +368,17 @@ namespace JianGongYun.TRTC
|
|||
|
||||
ConcurrentQueue<Mat> mats = new ConcurrentQueue<Mat>();
|
||||
|
||||
//int runFps = 0;//实时帧
|
||||
//Timer timer = new Timer((a) =>
|
||||
//{
|
||||
// Debug.Print($"runFps {runFps}. leavingsMat {mats.Count}.");
|
||||
// Interlocked.Exchange(ref runFps, 0);
|
||||
//}, null, 0, 1000);
|
||||
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();
|
||||
timer.Dispose();
|
||||
};
|
||||
|
||||
//帧合并线程
|
||||
|
@ -453,31 +485,32 @@ namespace JianGongYun.TRTC
|
|||
Skip2:
|
||||
|
||||
mats.Enqueue(BackgroundFrame.CvtColor(ColorConversionCodes.BGRA2BGR));
|
||||
//Interlocked.Increment(ref runFps);
|
||||
Interlocked.Increment(ref runFps);
|
||||
stopwatch.Stop();
|
||||
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;//理论休眠时间再去掉补偿时间
|
||||
//Debug.Print($"video frame run {stopwatch.ElapsedMilliseconds}. lastsleep {lastsleep}. sum {(stopwatch.ElapsedMilliseconds + lastsleep)}");
|
||||
//if (lastsleep > 0)
|
||||
//{
|
||||
// Thread.Sleep(lastsleep);
|
||||
//}
|
||||
if (liveWinMode.IsLive && sleep > 0)
|
||||
var sleep = delay - (int)stopwatch.ElapsedMilliseconds - 1;//每帧时间减去每帧处理时间为sleep时间//视频实际时长偏短,再减1是微调
|
||||
if (sleep > 0)
|
||||
{
|
||||
if (delayEqualize == 0)
|
||||
{
|
||||
Thread.Sleep(sleep);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
delayEqualize += sleep;
|
||||
if (delayEqualize > 0)
|
||||
{
|
||||
Thread.Sleep(delayEqualize);
|
||||
delayEqualize = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (sleep < 0)//如果处理时间超过了每帧时间,记录下来
|
||||
{
|
||||
delayEqualize += sleep;
|
||||
}
|
||||
//Debug.Print($"video frame run {stopwatch.ElapsedMilliseconds}. sleep{sleep}. delayEqualize {delayEqualize}. delay {delay}.");
|
||||
}
|
||||
BackgroundFrame?.Dispose();
|
||||
BackgroundFrame = null;
|
||||
|
@ -487,9 +520,8 @@ namespace JianGongYun.TRTC
|
|||
//新开线程写文件,减少帧处理时间
|
||||
Task.Factory.StartNew(() =>
|
||||
{
|
||||
var delayEqualize = 0;//每帧时间补偿,在性能和其他因素影响下delay的时间不一定充足
|
||||
VideoWriter vw = new VideoWriter(videoFile, FourCC.H264, fps, BackgroundFrame.Size());
|
||||
Stopwatch stopwatch = new Stopwatch();//计时器
|
||||
VideoWriter vw = new VideoWriter(VideoTempPath, FourCC.H264, fps, BackgroundFrame.Size());
|
||||
//Stopwatch stopwatch = new Stopwatch();//计时器
|
||||
Debug.Print("开始写入视频线程");
|
||||
while (!end || mats.Count > 0)
|
||||
{
|
||||
|
@ -497,29 +529,11 @@ namespace JianGongYun.TRTC
|
|||
{
|
||||
if (mats.TryDequeue(out var frame))
|
||||
{
|
||||
stopwatch.Restart();
|
||||
//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);
|
||||
//}
|
||||
//stopwatch.Stop();
|
||||
//Debug.Print($"video frame write {stopwatch.ElapsedMilliseconds}");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -532,6 +546,28 @@ namespace JianGongYun.TRTC
|
|||
}
|
||||
}
|
||||
vw.Dispose();
|
||||
//合并视频
|
||||
var arguments = $@"-i ""{VideoTempPath}"" -i ""{AudioTempPath}"" -c:v copy -c:a copy -strict experimental -y ""{ResultFilePath}""";
|
||||
Process prc = new Process { StartInfo = new ProcessStartInfo { FileName = Path.Combine(Environment.CurrentDirectory, "ffmpeg.exe"), Arguments = arguments, CreateNoWindow = true, UseShellExecute = false } };
|
||||
prc.Start();
|
||||
prc.WaitForExit();
|
||||
if (File.Exists(VideoTempPath))
|
||||
{
|
||||
File.Delete(VideoTempPath);
|
||||
}
|
||||
if (File.Exists(AudioTempPath))
|
||||
{
|
||||
File.Delete(AudioTempPath);
|
||||
}
|
||||
CurrentLiveWindow.Dispatcher.Invoke(new Action(() =>
|
||||
{
|
||||
NoticeManager.NotifiactionShow.AddNotifiaction(new NotifiactionModel()
|
||||
{
|
||||
Title = "提醒",
|
||||
Content = $"成功保存直播视频,路径:{ResultFilePath}。",
|
||||
NotifiactionType = AduSkin.Controls.EnumPromptType.Success
|
||||
});
|
||||
}));
|
||||
Debug.Print("结束写入视频线程");
|
||||
}, TaskCreationOptions.LongRunning);
|
||||
|
||||
|
|
|
@ -52,15 +52,21 @@ namespace JianGongYun.TRTC.Windows
|
|||
Rad2.Foreground = color;
|
||||
Rad3.Foreground = color;
|
||||
Rad4.Foreground = color;
|
||||
if (LiveWindowViewModel.IsLive)
|
||||
{
|
||||
LiveClassroom.PauseAllView(false);//切前台启动实时预览渲染
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected override void OnDeactivated(EventArgs e)
|
||||
{
|
||||
base.OnDeactivated(e);
|
||||
if (LiveWindowViewModel.IsLive)
|
||||
{
|
||||
LiveClassroom.PauseAllView(true);//切后台停止实时预览渲染
|
||||
}
|
||||
}
|
||||
|
||||
private Window settingWindow;
|
||||
//设置按钮
|
||||
|
|
Loading…
Reference in New Issue