C语言:创建简单的流媒体服务器来播放.flv文件

news/2024/7/22 12:59:48/文章来源:https://blog.csdn.net/belldeep/article/details/139280082

编写  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(5);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>
  1. 用 Chrome 浏览器访问 http://localhost:5555/flv/  可以播放,测试 Edge 不支持。

  2. 也可以用 ffplay 测试是否能播放
    ffplay -i http://127.0.0.1:8080/test.flv

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_1053679.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《Java数据结构》--单链表详解

一.单链表的概念 1.概念 单链表是一种物理存储结构是非连续&#xff0c;非线性的但是在逻辑结构上是连续且线性的&#xff0c;链表是通过一个个结点来实现的&#xff0c;使每个相邻结点之间存在一定关系来将所有结点串起来&#xff0c;在物理存储上像是一条链子。 2.链表的原…

【数据分析】Numpy和Pandas库基本用法及实例--基于Japyter notebook实现

各位大佬好 &#xff0c;这里是阿川的博客 &#xff0c; 祝您变得更强 个人主页&#xff1a;在线OJ的阿川 大佬的支持和鼓励&#xff0c;将是我成长路上最大的动力 阿川水平有限&#xff0c;如有错误&#xff0c;欢迎大佬指正 承接上篇的博客 数据分析—技术栈和开发环境搭…

工作纪实50-Idea下载项目乱码

下载了公司的一份项目代码&#xff0c;发现是gbk格式的&#xff0c;但是我的日常习惯又是utf-8&#xff0c;下载项目以后全是乱码&#xff0c;一脸懵 借用网友的一张图&#xff0c;如果是一个一个文件这么搞&#xff0c;真的是费劲&#xff0c;好几百个文件&#xff01; 步骤…

React@16.x(11)ref

目录 1&#xff0c;介绍1.1&#xff0c;得到的结果 2&#xff0c;参数类型2.1&#xff0c;字符串&#xff08;不再推荐&#xff09;2.2&#xff0c;对象2.3&#xff0c;函数函数调用时机 3&#xff0c;注意点 1&#xff0c;介绍 reference 引用。和 vue 中的 refs 类似&#x…

rk3568_mutex

文章目录 前言1、什么是mutex?1.1mutex互斥体API函数二、实验2.1实验目的2.2源码2.3结果图前言 本文记录的是rk3568开发板基础上做的mutex实验 1、什么是mutex? mutex是互斥体,它是比信号量semaphore更加专业的机制。 在我们编写Linux驱动的时候遇到需要互斥的地方建议使用…

TypeScript系列之-- 数组和元组类型

数组的定义&#xff1a; 第一种&#xff0c;可以在元素类型后面接上[] let list: number[] [1, 2, 3]; 第二种方式是使用数组泛型&#xff0c;Array<元素类型> let list: Array<number> [1, 2, 3]; 如果数组想每一项放入不同数据怎么办&#xff1f;用元组类型…

UE5 双手握剑的实现(逆向运动学IK)

UE5 双手握剑的实现 IK 前言 什么是IK&#xff1f; UE官方给我们提供了很多对于IK处理的节点&#xff0c;比如ABRIK、Two Bone IK、Full Body IK 、CCD IK等&#xff0c;但是看到这&#xff0c;很多人就好奇了&#xff0c;什么是IK&#xff1f; 首先我们来看看虚幻小白人的骨…

leetcode-主持人调度(二)-110

题目要求 思路 1.先将开始时间和结束时间拆分放到两个数组中进行排序 2.如果开始的时间小于结束时间&#xff0c;说明目前没有空闲的人&#xff0c;需要增加人&#xff0c;如果大于等于&#xff0c;说明有人刚结束了主持&#xff0c;可以进行新的主持了&#xff0c;变更到下一…

Java实现对PDF、纵向、横向页面添加自定义水印功能

Java实现对PDF、纵向、横向页面添加自定义水印 效果图 -- 纵向 页面PDF使用到JAR Maven依赖版本效果图 -- 横向页面PDF 效果图 – 纵向 页面PDF 代码如下&#xff1a; 使用到JAR Maven依赖版本 <dependency><groupId>org.apache.pdfbox</groupId><artifa…

2024.05.28学习记录

1. 小林coding 计网复习 2.代码随想录刷题. 图论.和复习数组.链表 3.rosebush完成select组件

BLE蓝牙模块在车联网中的智能开锁、数据监控应用

随着科技的不断发展&#xff0c;车联网已经成为了汽车行业的一个热门话题。在这个领域中&#xff0c;BLE蓝牙模块发挥着重要的作用&#xff0c;特别是在智能开锁和数据监控方面的应用。本文将详细介绍BLE蓝牙模块在这两个方面的应用及其优势。   一、智能开锁   1.车辆远程…

安卓开发--安卓使用Echatrs绘制折线图

安卓开发--安卓使用Echatrs绘制折线图 前期资料安卓使用Echarts绘制折线图1.1 下载 Echarts 安卓资源1.2 新建assets文件1.3 新建布局文件1.4 在布局文件中布局WebView1.5 在活动文件中调用 最终效果 前期资料 Echarts 官网样式预览: https://echarts.apache.org/examples/zh/…

MySQL中视图是什么,有什么作用

目录 一、视图的简介 1.1 什么是视图&#xff1f; 1.2 为什么使用视图&#xff1f; 1.3 视图有哪些规则与限制&#xff1f; 1.4 视图能否更新&#xff1f; 二、视图的创建 三、视图的作用 3.1 用视图简化复杂的联结 3.2 用视图格式化检索出的数据 3.3 用视图过滤数据…

实现echarts多图联动效果

实现echarts多图联动效果 文章目录 实现echarts多图联动效果业务场景实现关键api代码示例&#xff08;vue&#xff09; 业务场景 提示&#xff1a;主要是记录一下多个echarts联动效果实现方案 这本来就是echarts本身自带的api&#xff0c;并没有多高级&#xff0c;奈何寻找的过…

关于MySQL特殊储存引擎的介绍

目录 ——什么是储存引擎&#xff1f; ——关于表的储存引擎查询和建表语句 ---查询建表引擎语句 ---查询当前数据库支持的储存引擎 ---指定建表的储存引擎 ——关于特殊储存引擎的介绍 ---INNODB 特点&#xff1a; 关于INNDB的文件&#xff1a; 逻辑储存结构 ---MyI…

利用cherry pick巧妙地将某次提交单独合并到其他分支

0. 引言 最近在进行系统的多版本并行开发&#xff0c;涉及一些共有基础功能提交时就遇到了麻烦&#xff0c;一份代码需要向多个版本分支进行同步&#xff0c;以保证多版本都能有更新该基础功能。 多次对比提交的方式显然会带来巨大的工作量。但实际上我们可以通过git的cherry…

ES 查询踩坑-全字段匹配

需求&#xff1a;name字段需要全匹配查询 name的映射 普通的must查询 GET power_engin/_search {"from": 0,"size": 10,"query": {"bool": {"must": [{"term": {"name": {"value": "尼…

Java时间类--JDK8

为什么JDK8会又新增时间相关类呢&#xff1f; ① JDK7的时间对象如果需要比较大小的话&#xff0c;必须都先转换成毫秒值&#xff1b;JDK8则不需要&#xff0c;可以直接比较。 ② JDK7的时间对象可以修改&#xff0c;在多线程环境下就会导致数据不安全&#xff1b;JDK8不能修改…

如何找到docker的run(启动命令)

使用python三方库进行 需要安装python解释器 安装runlike安装包 pip3 install runlike 运行命令 runlike -p <container_name> # 后面可以是容器名和容器id&#xff0c;-p参数是显示自动换行实验 使用docker启动一个jenkins 启动命令为 docker run -d \ -p 9002:80…

7个靠谱的副业赚钱方法,宝妈,上班族,学生党可以做的兼职副业

你是否也曾面临过这样的困境&#xff1a;生活费紧张&#xff0c;想要找份兼职来补贴家用或是满足自己的小心愿&#xff1f;别担心&#xff0c;今天我将带领你踏入这个丰富多彩的兼职世界&#xff0c;助你轻松达成月入过千的小目标&#xff01; 在我漫长的兼职探索旅程中&#…