直接上代码,一个函数搞定。

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
#include <stdio.h>
#include <tchar.h>

void SaveAsBMP(char *filename, unsigned char* image, int width, int height, int bpp)
{
BITMAPFILEHEADER bmpheader;
BITMAPINFOHEADER bmpinfo;
FILE *fp;

if ((fp = fopen(filename, "wb+")) == NULL) {
printf("open file failed!\n");
return;
}
// 4 Byte aligned
int stride = (((width * bpp) + 31) >> 5) << 2; // (( BPP * Width ) / 32) * 4
int img_data_size = stride * height;


bmpheader.bfType = 0x4d42;
bmpheader.bfReserved1 = 0;
bmpheader.bfReserved2 = 0;
bmpheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bmpheader.bfSize = bmpheader.bfOffBits + img_data_size;

bmpinfo.biSize = sizeof(BITMAPINFOHEADER);
bmpinfo.biWidth = width;
bmpinfo.biHeight = height;
bmpinfo.biPlanes = 1;
bmpinfo.biBitCount = bpp;
bmpinfo.biCompression = BI_RGB;
bmpinfo.biSizeImage = img_data_size; // it can be 0 when biCompression is BI_RGB.
bmpinfo.biXPelsPerMeter = 3780; // 96 * 39.370079 ~= 3780
bmpinfo.biYPelsPerMeter = 3780;
bmpinfo.biClrUsed = 0;
bmpinfo.biClrImportant = 0;

fwrite(&bmpheader, sizeof(bmpheader), 1, fp);
fwrite(&bmpinfo, sizeof(bmpinfo), 1, fp);

unsigned char *buffer = new unsigned char[img_data_size];

unsigned char* pImage = image;
unsigned char* pDest = buffer;

int pixel_w_size = width * bpp / 8;
pImage += pixel_w_size*(height - 1);

for (int i = 0; i < height; i++) {
memcpy(pDest, pImage, pixel_w_size);
pDest += stride;

//fwrite(pImage, pixel_w_size, 1, fp);
pImage -= pixel_w_size;
}

pImage = nullptr;

fwrite(buffer, img_data_size, 1, fp);
fclose(fp);

delete[] buffer;
buffer = nullptr;
}
阅读全文 »

通过 apt 安装的 Nginx 可以通过系统服务的方式进行启动,相当便捷,但 Nginx 目前还不可以后期动态添加模块的,所以只能通过编译安装了。

准备

更新,及安装必要工具。

sudo apt-get update
sudo apt-get install -y dpkg-dev

创建一个干净的目录,用于后面的编译工作。

mkdir build && cd build

获取 nginx 源码。执行以下代码后,会在当前目录将 nginx 的源码下载至 nginx-* , * 是版本号。

apt-get source nginx

获取 nginx-rtmp-module 源码。通过 git 获取,或者直接下载

git clone https://github.com/arut/nginx-rtmp-module.git
cd nginx-rtmp-module
git checkout $(git describe --abbrev=0 --tags)
阅读全文 »

从Windows商店安装Ubuntu。

从开始菜单打开 Ubuntu。

通过 cmd 切换默认用户为 root:

> ubuntu config --default-user root

重新打开 Ubuntu。

Arch Linux Downloads或镜像站 下载一个 archlinux-bootstrap.tar.gz, 并解压:

# wget https://mirrors.tuna.tsinghua.edu.cn/archlinux/iso/2018.05.01/archlinux-bootstrap-2018.05.01-x86_64.tar.gz
# tar -zxvf archlinux-bootstrap-2018.05.01-x86_64.tar.gz

修改 ~/root.x86_64/etc/pacman.d/mirrorlist, 选择需要的服务器,取消注释。

让WSL自动生成 /etc/resolv.conf:

# echo "# This file was automatically generated by WSL. To stop automatic generation of this file, remove this line." > ~/root.x86_64/etc/resolv.conf

退出所有 Ubuntu Shell, 在资源管理器中打开 %localappdata%\Packages, 并找到 CanonicalGroupLimited.UbuntuonWindows_ 开头的文件夹,删除 %localappdata%\Packages\CanonicalGroupLimited.UbuntuonWindows_*\LocalState\rootfs 中的 bin, etc, lib, lib64, sbin, srv, usr 和 var 等 8 个文件夹。

然后,移动 rootfs\root\root.x86_64 中的 bin, etc, lib, lib64, sbin, srv, usr 和 var 到 rootfs 中。

在另一个 Arch Linux 系统中构建 fakeroot-tcpAURglibc-wslAUR , 然后复制到你的 Windows 电脑。 (通过 --nocheck 选项可以在 makepkg 编译 glibc-wsl 时跳过一个非常耗时的测试套件) glibc-wsl 用于解决 这个bug。 而直到 System V IPC 被完全实现之前 fakeroot-tcp 都是必需的。 (详情)

在另一个 Arch Linux 系统中构建 fakeroot-tcpAUR , 然后复制到你的 Windows 电脑。直到 System V IPC 被完全实现之前 fakeroot-tcp 都是必需的。 (详情)

重新打开 Bash 以安装 Archlinux:

# pacman-key --init
# pacman-key --populate archlinux
# pacman -Syy
# pacman -U fakeroot-tcp-1.22-2-x86_64.pkg.tar.xz
# pacman -Syu base base-devel

注意:在安装 base 和 base-devel 时,需要取消 glibc 和 fakeroot 。

最后,增加一个普通账号。

# useradd -m -G wheel -s /bin/bash username
# passwd root
# passwd username

并通过 cmd 设置该账号为默认账号:

> ubuntu config --default-user username

引言

由于某个需求,需要在原有的 WPF 程序上内嵌浏览器,最终选定 CefSharp.WPF , 但是还是有不少的问题影响着使用体验,比如:最开始遇到的不能输入中文、能输入中文了输入法候选框或右键菜单却跑到屏幕左上角,使用搜狗等第三方输入法不能输入等等。

Google 上逛了很久,也试了很多方法,最后发现一个最简单好用的方案是借用 WinForm 控件。

阅读全文 »

Nginx 一般都是编译安装,不过它本身也提供了通过yum安装的方式,比如在CentOS 7中需要先安装 Yum 源:

1
rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm

之后就是常规的 yum -y install nginx

通过这一方式安装的Nginx已经可以通过系统服务的方式进行启动,相当便捷,但是很多有趣的第三方插件并没有能够加入,比如header-more-nginx-module,Nginx目前看来不像Tengine是可以后期动态添加模块的,所以解决的方案出了编译安装似乎没有其他的方式了。

不过Nginx编译只生成一个二进制文件,那么,如果获取yum安装的Nginx编译参数,之后使用同一版本的源代码进行编译,之后替换生成文件就可以了。

阅读全文 »

Winforms 跨线程更新 UI

在 Winforms 中, 所有的控件都包含 InvokeRequired 属性, 如果我们要更新UI,通过它我们可以判断是否需要调用 [Begin]Invoke.

直接使用

delegate void SetTextCallback(string text);

public void SetText(string text)
{
    if (InvokeRequired)
    {
        var d = new SetTextCallback(SetText);
        this.textBox1.Invoke(d, new object[] { text });
    }
    else
    {
        this.textBox1.Text = text;
    }
}

直接调用 SetText 即可。

阅读全文 »

更新 apt 包

sudo apt update

   

安装 MySQL

sudo apt install mysql-server mysql-client

安装 PHP 7

sudo apt install php-{cli,fpm}

安装PHP插件

sudo apt install php-{mcrypt,mbstring,curl,gd,mysql,xml}

安装 Nginx

sudo apt install nginx-full

配置Nginx, 使之支持PHP, 编辑/etc/nginx/sites-enabled/default, 在server段中找到以下一段并解除部分注释,使其如下:

# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
    include snippets/fastcgi-php.conf;

    # With php7.0-cgi alone:
    #fastcgi_pass 127.0.0.1:9000;
    # With php7.0-fpm:
    fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}

简单记录一下 ffmpeg 获取 DirectShow 设备数据的方法。本文所述的方法主要是对应Windows平台的。(由于 ffmpeg 输出编码为 UTF-8, 所以这里使用 Git Bash )

列出设备

$ ./ffmpeg -list_devices true -f dshow -i dummy
ffmpeg version 3.2.4 Copyright (c) 2000-2017 the FFmpeg developers
  built with gcc 6.3.0 (GCC)
[dshow @ 00000000001c23c0] DirectShow video devices (some may be both video and audio devices)
[dshow @ 00000000001c23c0]  "Integrated Webcam"
[dshow @ 00000000001c23c0]     Alternative name "@device_pnp_\\?\usb#vid_0c45&pid_6448&mi_00#7&2645f9e4&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global"
[dshow @ 00000000001c23c0]  "screen-capture-recorder"
[dshow @ 00000000001c23c0]     Alternative name "@device_sw_{860BB310-5D01-11D0-BD3B-00A0C911CE86}\{4EA69364-2C8A-4AE6-A561-56E4B5044439}"
[dshow @ 00000000001c23c0] DirectShow audio devices
[dshow @ 00000000001c23c0]  "麦克风 (High Definition Audio 设备)"
[dshow @ 00000000001c23c0]     Alternative name "@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{E26AD2BE-B335-41EC-BED5-40F982F21FF7}"
[dshow @ 00000000001c23c0]  "virtual-audio-capturer"
[dshow @ 00000000001c23c0]     Alternative name "@device_sw_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\{8E146464-DB61-4309-AFA1-3578E927E935}"
dummy: Immediate exit requested

查看设备选项

video

$ ./ffmpeg -list_options true -f dshow -i video="Integrated Webcam"
ffmpeg version 3.2.4 Copyright (c) 2000-2017 the FFmpeg developers
  built with gcc 6.3.0 (GCC)
[dshow @ 0000000000ea23e0] DirectShow video device options (from video devices)
[dshow @ 0000000000ea23e0]  Pin "捕获" (alternative pin name "0")
[dshow @ 0000000000ea23e0]   pixel_format=yuyv422  min s=640x480 fps=10 max s=640x480 fps=30
[dshow @ 0000000000ea23e0]   pixel_format=yuyv422  min s=640x480 fps=10 max s=640x480 fps=30
[dshow @ 0000000000ea23e0]   pixel_format=yuyv422  min s=352x288 fps=10 max s=352x288 fps=30
[dshow @ 0000000000ea23e0]   pixel_format=yuyv422  min s=352x288 fps=10 max s=352x288 fps=30
[dshow @ 0000000000ea23e0]   pixel_format=yuyv422  min s=320x240 fps=10 max s=320x240 fps=30
[dshow @ 0000000000ea23e0]   pixel_format=yuyv422  min s=320x240 fps=10 max s=320x240 fps=30
[dshow @ 0000000000ea23e0]   pixel_format=yuyv422  min s=176x144 fps=10 max s=176x144 fps=30
[dshow @ 0000000000ea23e0]   pixel_format=yuyv422  min s=176x144 fps=10 max s=176x144 fps=30
[dshow @ 0000000000ea23e0]   pixel_format=yuyv422  min s=160x120 fps=10 max s=160x120 fps=30
[dshow @ 0000000000ea23e0]   pixel_format=yuyv422  min s=160x120 fps=10 max s=160x120 fps=30
[dshow @ 0000000000ea23e0]   pixel_format=yuyv422  min s=1280x720 fps=11 max s=1280x720 fps=11
[dshow @ 0000000000ea23e0]   pixel_format=yuyv422  min s=1280x720 fps=11 max s=1280x720 fps=11
[dshow @ 0000000000ea23e0]   vcodec=mjpeg  min s=1280x720 fps=10 max s=1280x720 fps=30
[dshow @ 0000000000ea23e0]   vcodec=mjpeg  min s=1280x720 fps=10 max s=1280x720 fps=30
video=Integrated Webcam: Immediate exit requested

audio

$ ./ffmpeg -list_options true -f dshow -i audio="麦克风 (High Definition Audio 设备)"
ffmpeg version 3.2.4 Copyright (c) 2000-2017 the FFmpeg developers
  built with gcc 6.3.0 (GCC)
[dshow @ 00000000024d24a0] DirectShow audio only device options (from audio devices)
[dshow @ 00000000024d24a0]  Pin "Capture" (alternative pin name "Capture")
[dshow @ 00000000024d24a0]   min ch=1 bits=8 rate= 11025 max ch=2 bits=16 rate= 44100
    Last message repeated 22 times
audio=麦克风 (High Definition Audio 设备): Immediate exit requested

TeamTalk 是蘑菇街开源的一款企业办公即时通信软件,最初是为自己内部沟通而做的 IM 工具。

支持的平台:

  • Windows
  • Mac
  • iOS
  • Android

Gethub: https://github.com/mogujie/TeamTalk

阅读全文 »

记录 TeamTalk Server 的部署过程,仅供大家参考。

为了简化问题,全程采用 root 操作。

编译前准备

环境

操作系统: Ubuntu 16.04.2 LTS (GNU/Linux 4.4.0-62-generic x86_64)
域名: teamtalk.naturalwill.me
IP: 192.168.1.70
阅读全文 »