深圳网站空间门户网站用途

张小明 2026/1/7 10:24:55
深圳网站空间,门户网站用途,建设银行网站最近都打不开吗,淄博市建设档案馆网站Java精选面试题#xff08;微信小程序#xff09;#xff1a;5000道面试题和选择题#xff0c;包含Java基础、并发、JVM、线程、MQ系列、Redis、Spring系列、Elasticsearch、Docker、K8s、Flink、Spark、架构设计、大厂真题等#xff0c;在线随时刷题#xff01; 1. 环境…Java精选面试题微信小程序5000道面试题和选择题包含Java基础、并发、JVM、线程、MQ系列、Redis、Spring系列、Elasticsearch、Docker、K8s、Flink、Spark、架构设计、大厂真题等在线随时刷题1. 环境准备1.1 ZLMediaKit 安装配置下载安装# 拉取镜像 docker pull zlmediakit/zlmediakit:master # 启动 docker run -d \ --name zlm-server \ -p 1935:1935 \ -p 8099:80 \ -p 8554:554 \ -p 10000:10000 \ -p 10000:10000/udp \ -p 8000:8000/udp \ -v /docker-volumes/zlmediakit/conf/config.ini:/opt/media/conf/config.ini \ zlmediakit/zlmediakit:master配置文件 (config.ini)[hls] broadcastRecordTs0 deleteDelaySec300 # 推流的视频保存多久(5分钟) fileBufSize65536 filePath./www # 保存路径 segDur2 # 单个.ts 切片时长秒。 segNum1000 # 直播时.m3u8 里最多同时保留多少个切片。 segRetain9999 # 磁盘上实际保留多少个历史切片启动服务# 查看启动状态 docker logs -f zlm-server1.2 FFmpeg 安装# 下载路径 https://www.gyan.dev/ffmpeg/builds/这两个都可以选配置环境变量C:\ffmpeg\ffmpeg-7.0.2-essentials_build\bin找到 bin 目录将其配到 path 环境变量中。出来版本就成功了。2. Spring Boot 后端实现2.1 添加依赖dependencies !-- 进程管理 -- dependency groupIdorg.apache.commons/groupId artifactIdcommons-exec/artifactId version1.3/version /dependency /dependencies2.2 推流配置类package com.lyk.plugflow.config; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; Data Component ConfigurationProperties(prefix stream) public class StreamConfig { /** * ZLMediaKit服务地址 */ private String zlmHost; /** * RTMP推流端口 */ private Integer rtmpPort; /** * HTTP-FLV拉流端口 */ private Integer httpPort; /** * FFmpeg可执行文件路径 */ private String ffmpegPath; /** * 视频存储路径 */ private String videoPath; }2.3 推流服务类package com.lyk.plugflow.service; import com.lyk.plugflow.config.StreamConfig; import lombok.extern.slf4j.Slf4j; import org.apache.commons.exec.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.io.ByteArrayOutputStream; import java.io.File; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; Slf4j Service public class StreamService { Autowired private StreamConfig streamConfig; // 存储推流进程 private final MapString, DefaultExecutor streamProcesses new ConcurrentHashMap(); // 添加手动停止标记 private final MapString, Boolean manualStopFlags new ConcurrentHashMap(); /** * 开始推流 */ public boolean startStream(String videoPath, String streamKey) { try { // 检查视频文件是否存在 File videoFile new File(videoPath); if (!videoFile.exists()) { log.error(视频文件不存在: {}, videoPath); return false; } // 构建RTMP推流地址 String rtmpUrl String.format(rtmp://%s:%d/live/%s, streamConfig.getZlmHost(), streamConfig.getRtmpPort(), streamKey); // 构建FFmpeg命令 CommandLine cmdLine getCommandLine(videoPath, rtmpUrl); // 创建执行器 DefaultExecutor executor new DefaultExecutor(); executor.setExitValue(0); // 设置watchdog用于进程管理 ExecuteWatchdog watchdog new ExecuteWatchdog(ExecuteWatchdog.INFINITE_TIMEOUT); executor.setWatchdog(watchdog); // 设置输出流 ByteArrayOutputStream outputStream new ByteArrayOutputStream(); PumpStreamHandler streamHandler new PumpStreamHandler(outputStream); executor.setStreamHandler(streamHandler); // 异步执行 executor.execute(cmdLine, new ExecuteResultHandler() { Override public void onProcessComplete(int exitValue) { log.info(推流完成, streamKey: {}, exitValue: {}, streamKey, exitValue); streamProcesses.remove(streamKey); } Override public void onProcessFailed(ExecuteException e) { boolean isManualStop manualStopFlags.remove(streamKey); if (isManualStop) { log.info(推流已手动停止, streamKey: {}, streamKey); } else { log.error(推流失败, streamKey: {}, error: {}, streamKey, e.getMessage()); } streamProcesses.remove(streamKey); } }); // 保存进程引用 streamProcesses.put(streamKey, executor); log.info(开始推流, streamKey: {}, rtmpUrl: {}, streamKey, rtmpUrl); return true; } catch (Exception e) { log.error(推流启动失败, e); return false; } } private CommandLine getCommandLine(String videoPath, String rtmpUrl) { CommandLine cmdLine new CommandLine(streamConfig.getFfmpegPath()); cmdLine.addArgument(-re); // 按原始帧率读取 cmdLine.addArgument(-i); cmdLine.addArgument(videoPath); cmdLine.addArgument(-c:v); cmdLine.addArgument(libx264); // 视频编码 cmdLine.addArgument(-c:a); cmdLine.addArgument(aac); // 音频编码 cmdLine.addArgument(-f); cmdLine.addArgument(flv); // 输出格式 cmdLine.addArgument(-flvflags); cmdLine.addArgument(no_duration_filesize); cmdLine.addArgument(rtmpUrl); return cmdLine; } /** * 停止推流 */ public boolean stopStream(String streamKey) { try { DefaultExecutor executor streamProcesses.get(streamKey); if (executor ! null) { // 设置手动停止标记 manualStopFlags.put(streamKey, true); ExecuteWatchdog watchdog executor.getWatchdog(); if (watchdog ! null) { watchdog.destroyProcess(); } else { log.warn(进程没有watchdog无法强制终止, streamKey: {}, streamKey); } streamProcesses.remove(streamKey); log.info(停止推流成功, streamKey: {}, streamKey); return true; } return false; } catch (Exception e) { log.error(停止推流失败, e); return false; } } /** * 获取拉流地址 */ public String getPlayUrl(String streamKey, String protocol) { return switch (protocol.toLowerCase()) { case flv - String.format(http://%s:%d/live/%s.live.flv, streamConfig.getZlmHost(), streamConfig.getHttpPort(), streamKey); case hls - String.format(http://%s:%d/live/%s/hls.m3u8, streamConfig.getZlmHost(), streamConfig.getHttpPort(), streamKey); default - null; }; } /** * 检查推流状态 */ public boolean isStreaming(String streamKey) { return streamProcesses.containsKey(streamKey); } }2.4 配置文件stream: zlm-host: 192.168.159.129 rtmp-port: 1935 http-port: 8099 ffmpeg-path: ffmpeg video-path: \videos\ # 文件上传配置 spring: servlet: multipart: max-file-size: 1GB max-request-size: 1GB3. 使用说明3.1 推流流程• 启动 ZLMediaKit 服务• 上传视频文件到服务器• 调用推流接口指定视频路径和推流密钥• Spring Boot 执行 FFmpeg 命令推流到 ZLMediaKit3.2 播放流程• 获取推流地址HTTP-FLV 或 HLS• 支持实时播放和回放ffmpeg -re -i C:\Users\lyk19\Videos\8月9日.mp4 -c:v libx264 -preset ultrafast -tune zerolatency -c:a aac -ar 44100 -b:a 128k -f flv rtmp://192.168.159.129:1935/live/stream• 前端播放!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 titleFLV直播播放器/title style body { margin: 0; padding: 20px; font-family: Arial, sans-serif; background-color: #f0f0f0; } .player-container { max-width: 800px; margin: 0 auto; background: white; border-radius: 8px; padding: 20px; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); } #videoElement { width: 100%; height: 450px; background-color: #000; border-radius: 4px; } .controls { margin-top: 15px; text-align: center; } button { padding: 10px 20px; margin: 0 5px; border: none; border-radius: 4px; background-color: #007bff; color: white; cursor: pointer; font-size: 14px; } button:hover { background-color: #0056b3; } button:disabled { background-color: #ccc; cursor: not-allowed; } .status { margin-top: 10px; padding: 10px; border-radius: 4px; text-align: center; } .status.success { background-color: #d4edda; color: #155724; } .status.error { background-color: #f8d7da; color: #721c24; } .status.info { background-color: #d1ecf1; color: #0c5460; } /style /head body div classplayer-container h1FLV直播播放器/h1 video idvideoElement controls muted 您的浏览器不支持视频播放 /video div classcontrols button idplayBtn播放/button button idpauseBtn disabled暂停/button button idstopBtn disabled停止/button button idmuteBtn静音/button /div div idstatus classstatus info 准备就绪点击播放开始观看直播 /div /div !-- 使用flv.js库 -- script srchttps://cdn.jsdelivr.net/npm/flv.js1.6.2/dist/flv.min.js/script script let flvPlayer null; const videoElement document.getElementById(videoElement); const playBtn document.getElementById(playBtn); const pauseBtn document.getElementById(pauseBtn); const stopBtn document.getElementById(stopBtn); const muteBtn document.getElementById(muteBtn); const statusDiv document.getElementById(status); // 你的流地址 const streamUrl http://192.168.159.129:8099/live/stream.live.flv; function updateStatus(message, type) { statusDiv.textContent message; statusDiv.className status ${type}; console.log([${type.toUpperCase()}] ${message}); } function updateButtons(playEnabled, pauseEnabled, stopEnabled) { playBtn.disabled !playEnabled; pauseBtn.disabled !pauseEnabled; stopBtn.disabled !stopEnabled; } // 检查浏览器支持 if (!flvjs.isSupported()) { updateStatus(您的浏览器不支持FLV播放请使用Chrome、Firefox或Edge浏览器, error); playBtn.disabled true; } // 播放功能 playBtn.addEventListener(click, function () { try { if (flvPlayer) { flvPlayer.destroy(); } // 创建FLV播放器 flvPlayer flvjs.createPlayer({ type: flv, url: streamUrl, isLive: true }, { enableWorker: false, lazyLoad: true, lazyLoadMaxDuration: 3 * 60, deferLoadAfterSourceOpen: false, autoCleanupSourceBuffer: true, enableStashBuffer: false }); flvPlayer.attachMediaElement(videoElement); flvPlayer.load(); // 监听事件 flvPlayer.on(flvjs.Events.ERROR, function (errorType, errorDetail, errorInfo) { console.error(FLV播放器错误:, errorType, errorDetail, errorInfo); updateStatus(播放错误: ${errorDetail}, error); }); flvPlayer.on(flvjs.Events.LOADING_COMPLETE, function () { updateStatus(流加载完成, success); }); flvPlayer.on(flvjs.Events.RECOVERED_EARLY_EOF, function () { updateStatus(从早期EOF恢复, info); }); // 开始播放 videoElement.play().then(() { updateStatus(正在播放直播流, success); updateButtons(false, true, true); }).catch(error { console.error(播放失败:, error); updateStatus(播放失败: error.message, error); }); } catch (error) { console.error(创建播放器失败:, error); updateStatus(创建播放器失败: error.message, error); } }); // 暂停功能 pauseBtn.addEventListener(click, function () { if (videoElement !videoElement.paused) { videoElement.pause(); updateStatus(播放已暂停, info); updateButtons(true, false, true); } }); // 停止功能 stopBtn.addEventListener(click, function () { if (flvPlayer) { flvPlayer.pause(); flvPlayer.unload(); flvPlayer.destroy(); flvPlayer null; } videoElement.src ; videoElement.load(); updateStatus(播放已停止, info); updateButtons(true, false, false); }); // 静音功能 muteBtn.addEventListener(click, function () { videoElement.muted !videoElement.muted; muteBtn.textContent videoElement.muted ? 取消静音 : 静音; updateStatus(videoElement.muted ? 已静音 : 已取消静音, info); }); // 视频事件监听 videoElement.addEventListener(loadstart, function () { updateStatus(开始加载视频流..., info); }); videoElement.addEventListener(canplay, function () { updateStatus(视频流已准备就绪, success); }); videoElement.addEventListener(playing, function () { updateStatus(正在播放直播流, success); updateButtons(false, true, true); }); videoElement.addEventListener(pause, function () { updateStatus(播放已暂停, info); updateButtons(true, false, true); }); videoElement.addEventListener(error, function (e) { updateStatus(视频播放出错, error); updateButtons(true, false, false); }); /script /body /html来源https://blog.csdn.net/weixin_73916358公众号“Java精选”所发表内容注明来源的版权归原出处所有无法查证版权的或者未注明出处的均来自网络系转载转载的目的在于传递更多信息版权属于原作者。如有侵权请联系笔者会第一时间删除处理 最近有很多人问有没有读者或者摸鱼交流群加入方式很简单公众号Java精选回复“加群”即可入群 点击“阅读原文”了解更多精彩内容文章有帮助的话点在看转发吧
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

东盟建设集团有限公司网站dw网页制作教程视频简单第二期

Awk编程:表达式、系统变量及应用示例 1. 表达式基础 表达式在数据存储、操作和检索方面与sed有很大不同,但它是大多数编程语言的常见特性。表达式经过求值后会返回一个值,它由数字和字符串常量、变量、运算符、函数和正则表达式组合而成。 1.1 常量 常量有两种类型:字符…

张小明 2026/1/6 16:02:57 网站建设

网站不做备案wordpress侧边栏图片

量子计算中的叠加与纠缠:从经典模拟到量子实现 1. 引言 在经典计算中,我们处理的是确定的比特值,要么是 0,要么是 1。而量子计算引入了两个独特的概念:叠加和纠缠,这使得量子计算在某些方面能够超越经典计算的能力。上一次我们介绍了叠加的概念,它允许量子比特同时处于…

张小明 2025/12/22 21:16:10 网站建设

舟山公司做网站代理公司英文

永磁同步电机无位置传感器算法仿真,低速IF中高速龙贝格观测器,这是工程中最常用最成熟的方法。 低速采用流频比IF控制,转速开环,电流闭环,转速和位置角度使用参考转速和计算的参考位置。 中高速采用了基于龙贝格观测器…

张小明 2025/12/22 21:14:08 网站建设

移动网站开发流行百色seo外包

基于Spring Boot的二手车交易市场管理系统是一个功能全面、用户友好、安全可靠的在线二手车交易平台。以下是对该系统的详细介绍: 一、系统架构与技术栈 后端:采用Spring Boot框架作为后端开发工具,负责处理业务逻辑,如车辆信息…

张小明 2025/12/22 21:12:05 网站建设

陕西网站制作开网店的流程视频

如果你是正在电脑前抓耳挠腮、对着空白文档焦虑到脱发的毕业生;如果你是那个被导师催稿催到崩溃、却还卡在文献综述的可怜虫;如果你是预算有限,连知网查重都觉得肉疼的穷学生——那么,恭喜你,这篇深度测评就是为你量身…

张小明 2026/1/1 18:27:43 网站建设

网站建设上海诏业建设运营网络或提供网络服务

Go-nunu实战解析:5大核心优势助你高效构建企业级Go应用 【免费下载链接】nunu A CLI tool for building Go applications. 项目地址: https://gitcode.com/GitHub_Trending/nu/nunu 还在为Golang项目架构设计而烦恼吗?面对复杂的依赖管理、重复的…

张小明 2026/1/3 3:08:54 网站建设