编写 httpFlv_server.cpp 如下
#include <iostream>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <WinSock2.h>
#include <WS2tcpip.h>
#pragma comment(lib, "ws2_32.lib")char* get_filename(char* path) {char* last_slash = strrchr(path, '/');// 对于Windows系统,应该是 '\'if (last_slash == NULL) {last_slash = strrchr(path, '\\');}if (last_slash == NULL) {return path;} else {return last_slash + 1;}
}int main(int argc, char *argv[])
{int port = 8080;char* path;if (argc ==2){path = argv[1];} else if (argc ==3){port = atoi(argv[1]);path = argv[2];} else {printf(" usage: httpFlv_server port /your/video.flv ");return 1;}if (port <6000 || port >65500){printf(" 6000 <= port <= 65500 ");return 2;}printf("%s\n", path);int n = strlen(path);if (n >80){printf(" file path is too long.");return 3;}if (n < 8){printf(" file path is too short.");return 3;}char* ext = &path[n-4];if (strcmp(ext, ".flv") !=0){printf(" file ext is not .flv ");return 3;}printf("httpFlv_server http://127.0.0.1:%d/%s\n", port, get_filename(path));WSADATA wsaData;if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0){perror("WSAStartup error");return -1;}SOCKET serverFd;SOCKADDR_IN server_addr;server_addr.sin_family = AF_INET;server_addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//server_addr.sin_addr.s_addr = inet_addr("192.168.2.61");server_addr.sin_port = htons(port);serverFd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (bind(serverFd, (SOCKADDR*)&server_addr, sizeof(SOCKADDR)) == SOCKET_ERROR) {perror("socket bind error");return -1;}if (listen(serverFd, SOMAXCONN) < 0) {perror("socket listen error");return -1;}constexpr char http_headers[] = \"HTTP/1.1 200 OK\r\n" \"Access-Control-Allow-Origin: * \r\n" \"Content-Type: video/x-flv\r\n" \"Content-Length: -1\r\n" \"Connection: Keep-Alive\r\n" \"Expires: -1\r\n" \"Pragma: no-cache\r\n" \"\r\n";int http_headers_len = strlen(http_headers);/*constexpr char http_headers[] = \
"HTTP/1.1 200 OK\r\n" \
"Access-Control-Allow-Origin: * \r\n" \
"Cache-Control: no-cache\r\n" \
"Content-Type: video/x-flv\r\n" \
"Connection: close\r\n" \
"Expires: -1\r\n" \ //设置资源的有效期来控制http的缓存
"Pragma: no-cache\r\n" \ //用于客户端发送的请求中。客户端会要求所有的中间服务器不返回缓存的资源
"\r\n"
;*/while (true){printf(" waiting ...");int len = sizeof(SOCKADDR);SOCKADDR_IN accept_addr;int clientFd = accept(serverFd, (SOCKADDR*)&accept_addr, &len);//const char* clientIp = inet_ntoa(accept_addr.sin_addr);if (clientFd == SOCKET_ERROR) {perror("accept connection error");break;}printf(" connect ... clientFd=%d\n", clientFd);unsigned char buf[4096];char bufRecv[2001] = { 0 };FILE* fp;fp = fopen(path, "rb");if (!fp) {printf("Error: fopen %s failed!", path);break;}else {int times = 0;while (true) {times++;if (times == 1) {int bufRecvSize = recv(clientFd, bufRecv, 2000, 0);printf("bufRecvSize=%d, bufRecv=%s\n", bufRecvSize, bufRecv);send(clientFd, http_headers, http_headers_len, 0);}else {//usleep(1000 * 100);Sleep(10);int bufLen = fread(buf, 1, sizeof(buf), fp);// fseek(srcFile, 0, SEEK_CUR);int ret = send(clientFd, (char*)buf, bufLen, 0);if (ret <= 0) {break;}else {//printf("send bufLen=%d,ret=%d \n", bufLen, ret);}}}}if (fp) {fclose(fp);}closesocket(clientFd);printf("close clientFd=%d\n", clientFd);}closesocket(serverFd);return 0;
}
编译 cl httpFlv_server.cpp /EHsc /utf-8
运行 httpFlv_server /flask/videos/test.flv
或者 编写 win_gcc.bat 如下
SET INCLUDE=D:\Strawberry\c\include
SET LIB=D:\Strawberry\c\x86_64-w64-mingw32\lib
g++ %1.cpp -o %1.exe -lws2_32
编译执行 win_gcc.bat httpFlv_server
npm i flv.js -save ;
cd D:\nodejs\node_modules\flv.js\dist ;
copy flv.min.js flv.min.js.map to /flask/static/
编写 flvPlayer.html 如下
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8" /><title> flv.js 播放器</title><script src="/static/flv.min.js"></script>
</head>
<body><video id="video1" width="1000" height="576" controls ></video><script>if (flvjs.isSupported()) {var video1 = document.getElementById('video1');var flvplayer = flvjs.createPlayer({type: 'flv', // 媒体类型: auto, flv, mp4isLive: false, // 是否是直播流,默认 trueurl: 'http://127.0.0.1:8080/test.flv'});flvplayer.attachMediaElement(video1);flvplayer.load(); // 加载流flvplayer.play(); // 播放流}</script>
</body>
</html>
-
用 Chrome 浏览器访问 http://localhost:5555/flv/ 可以播放,测试 Edge 不支持。
-
也可以用 ffplay 测试是否能播放
ffplay -i http://127.0.0.1:8080/test.flv