CSharp中处理H264的编码和解码

前言

开源的H264库

https://github.com/cisco/openh264

C#的封装

https://github.com/secile/OpenH264Lib.NET

示例代码:

https://gitee.com/psvmc/z-h264-tools

添加依赖

下面的这个命令并没有下载C#的封装库,只下载了C++的DLL(openh264-2.1.1-win32.dll/openh264-2.1.1-win64.dll)

1
Install-Package OpenH264.NET -Version 1.0.4

我没有使用这种方式,而是自己下载了最新版放在项目下openh264-2.3.1-win32.dll

生成事件=>生成前事件命令行:

1
xcopy /Y /d $(ProjectDir)\Libs\openh264-2.3.1-win32.dll $(TargetDir)

至于C#的封装我下载源码后,把目标设置为4.5.2,生成DLL后引用即可。

调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
namespace z_h264_tools
{
using System;
using System.Threading;
using Utils;

/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow
{
private bool _isStart;

public MainWindow()
{
InitializeComponent();
Closing += MainWindow_Closing;
ScreenTest();
}

private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
_isStart = false;
}

private void ScreenTest()
{
_isStart = true;
var encoder = new OpenH264Lib.Encoder("openh264-2.3.1-win32.dll");
var decoder = new OpenH264Lib.Decoder("openh264-2.3.1-win32.dll");

// setup encoder
float fps = 10.0f;
int bps = 5000 * 1000; // target bitrate. 5Mbps.
float keyFrameInterval = 2.0f; // insert key frame interval. unit is second.
encoder.Setup
(
1920,
1080,
bps,
fps,
keyFrameInterval,
(
data,
length,
frameType
) =>
{
// called when each frame encoded.
Console.WriteLine
(
@"Encord {0} bytes, frameType:{1}",
length,
frameType
);

// decode it to Bitmap again...
if (_isStart)
{
Dispatcher.Invoke
(
() =>
{
var bmp = decoder.Decode(data, length);
if (bmp != null)
{
Console.WriteLine(bmp.Size);
var bitmapImage = ZImageUtils.Bitmap2BitmapImage(bmp);
MImg.Source = bitmapImage;
bmp.Dispose();
}
}
);
}
}
);
new Thread
(
() =>
{
while (_isStart)
{
var screen = ZScreenUtils.GetScreen();
encoder.Encode(screen);
screen.Dispose();
Thread.Sleep(1000 / 10);
}
}
).Start();
}
}
}