skyline的虚实融合
程序员文章站
2022-04-28 21:27:40
...
背景:
skyline本身的直播推流只满足RTSP这种方式, 但是RTMP等其它格式并不满足. 又加上,需要对当前的投影视频,单帧要做处理的话,完全做不到.所以,这个功能并满足不了项目需求
开发的一些关键知识:
1. 首先要对RTSP或者RTMP的协议做一定了解.
2.对图像以及视频流有相关了解.
3.掌握异步多线程以及双缓存的相关概念;
4.一个组件
功能展示:
这个大体做到了对直播的播放,停止,帧处理之后的再展示
开发设计:
1.首先我们要设计一个中间缓存Imagequeue,这个类主要是对每帧的图像数据做缓存并处理之后,转发
2.设计一个异步线程,实时的对这个类进行帧缓存以及帧读取,并依照间隔,不停的刷新里面的数据,这样,就可以用10M大小的内存,就可以模拟视频的播放.
这里面记录一下关键代码部分
private void SaveImage()
{
try
{
if (!_QueueList.IsEmpty)
{
#if true
//方式一:
if (recordPreviewFile != null && recordPreviewFile.Length > 1) updateImageSigle(recordPreviewFile, true);
recordPreviewFile = "";
#endif
ImageStruct getTempData;
_QueueList.TryDequeue(out getTempData);
string strBmpFile = $"{PathDir}{ImageNumbers}.jpg";
if (ImageNumbers % RecordSteps == 0) recordPreviewFile = strBmpFile;
if (getTempData != null)
{
System.IO.MemoryStream ms = null;
getTempData.imageSource.Dispatcher.Invoke(new Action(() =>
{
ms = new System.IO.MemoryStream();
BmpBitmapEncoder encoder = new BmpBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create((BitmapSource)getTempData.imageSource));
encoder.Save(ms);
}));
if (ms == null) return;
Bitmap bmp = new Bitmap(ms);
bmp.Save(strBmpFile, ImageFormat.Jpeg);
getTempData.Dispose();
ms.Close();
ms.Dispose();
bmp.Dispose();
GC.Collect();
#if false
//方式二:
if (recordNumber >= 0 && recordNumber % stepnumber == 0)
{
updateImageSigle(strBmpFile, true);
recordNumber = recordNumber % stepnumber;
}
recordNumber++;
updateImageSigle(strBmpFile, false);
#endif
}
ImageNumbers = (ImageNumbers++) > 0 ? ImageNumbers % CacheNumber : ImageNumbers;
Console.WriteLine(strBmpFile + " " + _QueueList.Count);
}
}
catch (Exception ex)
{
//GDI+错误忽略
Console.WriteLine($"输出数据异常: {ex.Message} {_QueueList.Count}");
return;
}
}
关键的这两个部分做好了之后.再设计一下UI
依据上述思路,我们就可以做到任意视频的播放.然后都不用自己做播放器.