如何实现在线视频播放?
yuyutoo 2025-01-06 16:13 4 浏览 0 评论
视频点播
1. 视频点播需求分析
1.1 需求描述
视频点播需求如下:
1、学生可以在windows浏览器上在线观看视频。
2、播放器具有快进、快退、暂停等基本功能。
1.2 视频点播解决方案
1.2.1 流媒体
- 流媒体
详细参考:https://baike.baidu.com/item/%E6%B5%81%E5%AA%92%E4%BD%93/98740?fr=aladdin
概括理解:流媒体就是将视频文件分成许多小块儿,将这些小块儿作为数据包通过网络发送出去,实现一边传输视频 数据 包一边观看视频。
- 流式传输
在网络上传输音、视频信息有两个方式:下载和流式传输。
下载:就是把音、视频文件完全下载到本机后开始播放,它的特点是必须等到视频文件下载完成方可播放,播放等待时间较长,无法去播放还未下载的部分视频。
流式传输:就是客户端通过链接视频服务器实时传输音、视频信息,实现“边下载边播放”。
流式传输包括如下两种方式:
1) 顺序流式传输
即顺序下载音、视频文件,可以实现边下载边播放,不过,用户只能观看已下载的视频内容,无法快进到未下载的视频部分,顺序流式传输可以使用Http服务器来实现,比如Nginx、Apache等。
2)实时流式传输
实时流式传输可以解决顺序流式传输无法快进的问题,它与Http流式传输不同,它必须使用流媒体服务器并且使用流媒体协议来传输视频,它比Http流式传输复杂。常见的实时流式传输协议有RTSP、RTMP、RSVP等。
- 流媒体系统的概要结构
通过流媒体系统的概要结构学习流媒体系统的基本业务流程。
1、将原始的视频文件通过编码器转换为适合网络传输的流格式,编码后的视频直接输送给媒体服务器。
原始的视频文件通常是事先录制好的视频,比如通过摄像机、摄像头等录像、录音设备采集到的音视频文件,体积较大,要想在网络上传输需要经过压缩处理,即通过编码器进行编码 。
2、媒体服务获取到编码好的视频文件,对外提供流媒体数据传输接口,接口协议包括 :HTTP、RTSP、RTMP等
3、播放器通过流媒体协议与媒体服务器通信,获取视频数据,播放视频。
1.2.2 点播方案
本项目包括点播和直播两种方式,我们先调研点播的方案,如下:
1、 播放器通过 http协议从http服务器上下载视频文件进行播放
问题:必须等到视频下载完才可以播放,不支持快进到某个时间点进行播放
2、 播放器通过rtmp协议连接媒体服务器以实时流方式播放视频
使用rtmp协议需要架设媒体服务器,造价高,对于直播多采用此方案。
3、 播放器使用HLS协议连接http服务器(Nginx、Apache等)实现近实时流方式播放视频
HLS协议规定:基于Http协议,视频封装格式为ts,视频的编码格式为H264,音频编码格式为MP3、AAC或者AC-3
- HLS是什么 ?
HLS的工作方式是:将视频拆分成若干ts格式的小文件,通过m3u8格式的索引文件对这些ts小文件建立索引。一般10秒一个ts文件,播放器连接m3u8文件播放,当快进时通过m3u8即可找到对应的索引文件,并去下载对应的ts文件,从而实现快进、快退以近实时 的方式播放视频。
IOS、Android设备、及各大浏览器都支持HLS协议。
详细参考:https://baike.baidu.com/item/HLS/8328931?fr=aladdin
采用HLS方案即可实现边下载边播放,可以不用使用rtmp等流媒体协议,不用构建专用的媒体服务器,节省成本。
本项目点播方案确定为方案3。
2 FFmpeg 的基本使用
我们将视频录制完成后,使用视频编码软件对视频进行编码,本项目 使用FFmpeg对视频进行编码 。
下载 :ffmpeg-20180227-fa0c9d6-win64-static.zip,并解压,本教程将ffmpeg解压到了C:\Java_Soft\xczx\ffmpeg-20180227-fa0c9d6-win64-static下。
FFmpeg被许多开源项目采用,QQ影音、暴风影音、VLC等。
下载:FFmpeg https://www.ffmpeg.org/download.html#build-windows
将C:\Java_Soft\xczx\ffmpeg-20180227-fa0c9d6-win64-static\bin目录配置在path环境变量中。
简单的测试:
将一个.avi文件转成mp4、mp3、gif等。
比如我们将lucene.avi文件转成mp4,运行如下命令:
ffmpeg -i lucene.avi lucene.mp4
转成mp3:ffmpeg -i lucene.avi lucene.mp3
转成gif:ffmpeg -i lucene.avi lucene.gif
官方文档(英文):http://ffmpeg.org/ffmpeg.html
2.1 生成m3u8/ts文件
使用ffmpeg生成 m3u8的步骤如下:
第一步:先将avi视频转成mp4
ffmpeg.exe -i lucene.avi -c:v libx264 -s 1280x720 -pix_fmt yuv420p -b:a 63k -b:v 753k -r 18 .\lucene.mp4
下面把各参数意思大概讲讲,大概了解意思即可,不再此展开流媒体专业知识的讲解。
-c:v 视频编码为x264 ,x264编码是H264的一种开源编码格式。
-s 设置分辨率
-pix_fmt yuv420p:设置像素采样方式,主流的采样方式有三种,YUV4:4:4,YUV4:2:2,YUV4:2:0,它的作用是根据采样方式来从码流中还原每个像素点的YUV(亮度信息与色彩信息)值。
-b 设置码率,-b:a和-b:v分别表示音频的码率和视频的码率,-b表示音频加视频的总码率。码率对一个视频质量有很大的作用。
-r:帧率,表示每秒更新图像画面的次数,通常大于24肉眼就没有连贯与停顿的感觉了。
第二步:将mp4生成m3u8
ffmpeg -i lucene.mp4 -hls_time 10 -hls_list_size 0 -hls_segment_filename ./hls/lucene_%05d.ts ./hls/lucene.m3u8
-hls_time 设置每片的长度,单位为秒
-hls_list_size n: 保存的分片的数量,设置为0表示保存所有分片
-hls_segment_filename :段文件的名称,%05d表示5位数字
生成的效果是:将lucene.mp4视频文件每10秒生成一个ts文件,最后生成一个m3u8文件,m3u8文件是ts的索引文件。
使用VLC打开m3u8文件,测试播放效果,VLC 是一款自由、开源的跨平台多媒体播放器及框架,可播放大多数多媒体文件,以及 DVD、音频 CD、VCD 及各类流媒体协议。(http://www.videolan.org/)
3. 视频(媒资)处理
开发环境
1. 创建媒资数据库
导入shcool.sql
2. 创建媒资服务工程
基于springboot创建工程
3. 上传文件
3.1 断点续传解决方案
通常视频文件都比较大,所以对于媒资系统上传文件的需求要满足大文件的上传要求。http协议本身对上传文件大小没有限制,但是客户的网络环境质量、电脑硬件环境等参差不齐,如果一个大文件快上传完了网断了,电断了没有上传完成,需要客户重新上传,这是致命的,所以对于大文件上传的要求最基本的是断点续传。
什么是断点续传:
引用百度百科:断点续传指的是在下载或上传时,将下载或上传任务(一个文件或一个压缩包)人为的划分为几个部分,每一个部分采用一个线程进行上传或下载,如果碰到网络故障,可以从已经上传或下载的部分开始继续上传下载未完成的部分,而没有必要从头开始上传下载,断点续传可以提高节省操作时间,提高用户体验性。
上传流程如下:
1、上传前先把文件分成块
2、一块一块的上传,上传中断后重新上传,已上传的分块则不用再上传
3、各分块上传完成最后合并文件
文件下载则同理。
3.2 文件分块与合并
为了更好的理解文件分块上传的原理,下边用java代码测试文件的分块与合并。
3.3 文件分块
文件分块的流程如下:
1、获取源文件长度
2、根据设定的分块文件的大小计算出块数
3、从源文件读数据依次向每一个块文件写数据
//测试文件分块方法
@Test
public void testChunk() throws IOException {
File sourceFile = new File("F:/develop/ffmpeg/lucene.mp4");
// File sourceFile = new File("d:/logo.png");
String chunkPath = "F:/develop/ffmpeg/chunk/";
File chunkFolder = new File(chunkPath);
if(!chunkFolder.exists()){
chunkFolder.mkdirs();
}
//分块大小
long chunkSize = 1024*1024*1;
//分块数量
long chunkNum = (long) Math.ceil(sourceFile.length() * 1.0 / chunkSize );
if(chunkNum<=0){
chunkNum = 1;
}
//缓冲区大小
byte[] b = new byte[1024];
//使用RandomAccessFile访问文件
RandomAccessFile raf_read = new RandomAccessFile(sourceFile, "r");
//分块
for(int i=0;i<chunkNum;i++){
//创建分块文件
File file = new File(chunkPath+i);
boolean newFile = file.createNewFile();
if(newFile){
//向分块文件中写数据
RandomAccessFile raf_write = new RandomAccessFile(file, "rw");
int len = -1;
while((len = raf_read.read(b))!=-1){
raf_write.write(b,0,len);
if(file.length()>chunkSize){
break;
}
}
raf_write.close();
}
}
raf_read.close();
?
}
3.4 文件合并
文件合并流程:
1、找到要合并的文件并按文件合并的先后进行排序
2、创建合并文件
3、依次从合并的文件中读取数据向合并文件写入数据
//测试文件合并方法
@Test
public void testMerge() throws IOException {
//块文件目录
File chunkFolder = new File("F:/develop/ffmpeg/chunk/");
//合并文件
File mergeFile = new File("F:/develop/ffmpeg/lucene1.mp4");
if(mergeFile.exists()){
mergeFile.delete();
}
//创建新的合并文件
mergeFile.createNewFile();
//用于写文件
RandomAccessFile raf_write = new RandomAccessFile(mergeFile, "rw");
//指针指向文件顶端
raf_write.seek(0);
//缓冲区
byte[] b = new byte[1024];
//分块列表
File[] fileArray = chunkFolder.listFiles();
// 转成集合,便于排序
List<File> fileList = new ArrayList<File>(Arrays.asList(fileArray));
// 从小到大排序
Collections.sort(fileList, new Comparator<File>() {
@Override
public int compare(File o1, File o2) {
if (Integer.parseInt(o1.getName()) < Integer.parseInt(o2.getName())) {
return -1;
}
return 1;
}
});
//合并文件
for(File chunkFile:fileList){
RandomAccessFile raf_read = new RandomAccessFile(chunkFile,"rw");
int len = -1;
while((len=raf_read.read(b))!=-1){
raf_write.write(b,0,len);
?
}
raf_read.close();
}
raf_write.close();
?
}
4. 前端页面
WebUploader介绍
如何在web页面实现断点续传?
常见的方案有:
1、通过Flash上传,比如SWFupload、Uploadify。
2、安装浏览器插件,变相的pc客户端,用的比较少。
3、Html5
随着html5的流行,本项目采用Html5完成文件分块上传。
本项目使用WebUploader完成大文件上传功能的开发,WebUploader官网地址:http://fexteam.gz01.bdysite.com/webuploader/
使用WebUploader上传流程如下:
钩子方法
在webuploader中提供很多钩子方法,下边列出一些重要的:
本项目使用如下钩子方法:
1)before-send-file
在开始对文件分块儿之前调用,可以做一些上传文件前的准备工作,比如检查文件目录是否创建完成等。
2)before-send
在上传文件分块之前调用此方法,可以请求服务端检查分块是否存在,如果已存在则此分块儿不再上传。
3)after-send-file
在所有分块上传完成后触发,可以请求服务端合并分块文件。
注册钩子方法源代码:
WebUploader.Uploader.register({
"before-send-file":"beforeSendFile",
"before-send":"beforeSend",
"after-send-file":"afterSendFile"
}
构建WebUploader
使用webUploader前需要创建webUploader对象。
指定上传分块的地址:/api/media/upload/uploadchunk
// 创建uploader对象,配置参数
this.uploader = WebUploader.create(
{
swf:"/static/plugins/webuploader/dist/Uploader.swf",//上传文件的flash文件,浏览器不支持h5时启动flash
server:"/api/media/upload/uploadchunk",//上传分块的服务端地址,注意跨域问题
fileVal:"file",//文件上传域的name
pick:"#picker",//指定选择文件的按钮容器
auto:false,//手动触发上传
disableGlobalDnd:true,//禁掉整个页面的拖拽功能
chunked:true,// 是否分块上传
chunkSize:1*1024*1024, // 分块大小(默认5M)
threads:3, // 开启多个线程(默认3个)
prepareNextFile:true// 允许在文件传输时提前把下一个文件准备好
}
)
before-send-file
文件开始上传前前端请求服务端准备上传工作。
type:"POST",
url:"/api/media/upload/register",
data:{
// 文件唯一表示
fileMd5:this.fileMd5,
fileName: file.name,
fileSize:file.size,
mimetype:file.type,
fileExt:file.ext
}
before-send
上传分块前前端请求服务端校验分块是否存在。
type:"POST",
url:"/api/media/upload/checkchunk",
data:{
// 文件唯一表示
fileMd5:this.fileMd5,
// 当前分块下标
chunk:block.chunk,
// 当前分块大小
chunkSize:block.end-block.start
}
after-send-file
在所有分块上传完成后触发,可以请求服务端合并分块文件。
type:"POST",
url:"/api/media/upload/mergechunks",
data:{
fileMd5:this.fileMd5,
fileName: file.name,
fileSize:file.size,
mimetype:file.type,
fileExt:file.ext
}
页面效果
学员使用:
- 直接解压资料xc-ui-pc-teach到webstorm工作目录
- 通过nginx访问,在nginx中配置 (解决跨域)
server {
listen 82;
server_name localhost;
#视频中心
location / {
proxy_pass http://127.0.0.1:12000;
proxy_set_header Host $http_host;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Credentials true;
add_header Access-Control-Allow-Methods GET;
}
?
#媒资管理后台跨域
location ^~ /api/media/ {
proxy_pass http://127.0.0.1:9000/media/;
?
proxy_set_header Host $http_host;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Credentials true;
add_header Access-Control-Allow-Methods "GET,POST,OPTIONS";
}
}
可以访问 http://127.0.0.1:12000/#/media/upload 或者 http://localhost:82/#/media/upload/ 查看页面效果。
5. 媒资服务端编写
服务端需要实现如下功能:
1、上传前检查上传环境
检查文件是否上传,已上传则直接返回。
检查文件上传路径是否存在,不存在则创建。
2、分块检查
检查分块文件是否上传,已上传则返回true。
未上传则检查上传路径是否存在,不存在则创建。
3、分块上传
将分块文件上传到指定的路径。
4、合并分块
将所有分块文件合并为一个文件。
在数据库记录文件信息。
- 由于上传过程复杂,开发时按业务流程分别实现。
- 配置
application.yml配置上传文件的路径:
xc-service-manage-media:
upload-location: C:/school/video/ # 媒资保存路径
ffmpeg-path: C:/Java_Soft/xczx/ffmpeg-20180227-fa0c9d6-win64-static/bin/ffmpeg.exe # ffmpeg路径
- 定义Dao
使用mybatis-plus
@Mapper
@Component
public interface FileMsgMapper extends BaseMapper<FileMsg> {
}
- 定义controller
@RestController
@RequestMapping("/media/upload")
public class MediaUploadController {
?
?
@Autowired
MediaUploadService mediaUploadService;
?
/**
* 文件上传前的注册
*/
?
@PostMapping("/register")
public ResponseResult register(String fileMd5, String fileName, Long fileSize, String mimetype, String fileExt) {
?
return mediaUploadService.register(fileMd5, fileName, fileSize, mimetype, fileExt);
?
}
?
/**
* 检测分块
*
* @param fileMd5
* @param chunk
* @param chunkSize
* @return
*/
?
@PostMapping("/checkchunk")
public ResponseResult checkchunk(String fileMd5, Integer chunk, Integer chunkSize) {
return mediaUploadService.checkchunk(fileMd5, chunk, chunkSize);
}
?
/**
* 上传分块
*
* @param file
* @param fileMd5
* @param chunk
* @return
*/
@PostMapping("/uploadchunk")
public ResponseResult uploadchunk(MultipartFile file, String fileMd5, Integer chunk) {
return mediaUploadService.uploadchunk(file, fileMd5, chunk);
}
?
/**
* 合并分块
*
* @param fileMd5
* @param fileName
* @param fileSize
* @param mimetype
* @param fileExt
* @return
*/
@PostMapping("/mergechunks")
public ResponseResult mergechunks(String fileMd5, String fileName, Long fileSize, String mimetype, String fileExt) {
return mediaUploadService.mergechunks(fileMd5, fileName, fileSize, mimetype, fileExt);
}
}
?
- 定义service (略)由于代码过多,请参见源码。
现在视频已经通过断点续传的方式,上传到了我们的媒资服务器, 接下来就要使用FFmpeg将视频转换成 流媒体。
6.视频处理技术方案
如何通过程序进行视频处理?
ffmpeg是一个可行的视频处理程序,可以通过Java调用ffmpeg.exe完成视频处理。
在java中可以使用Runtime类和Process Builder类两种方式来执行外部程序,工作中至少掌握一种。
本项目使用Process Builder的方式来调用ffmpeg完成视频处理。
关于Process Builder的测试如下 :
@Test
public void testProcessBuilder(){
ProcessBuilder processBuilder = new ProcessBuilder();
// processBuilder.command("ping","127.0.0.1");
processBuilder.command("ipconfig");
//将标准输入流和错误输入流合并,通过标准输入流读取信息
processBuilder.redirectErrorStream(true);
try {
//启动进程
Process start = processBuilder.start();
//获取输入流
InputStream inputStream = start.getInputStream();
//转成字符输入流
InputStreamReader inputStreamReader = new InputStreamReader(inputStream,"gbk");
int len = -1;
char[] c = new char[1024];
StringBuffer outputString = new StringBuffer();
//读取进程输入流中的内容
while ((len= inputStreamReader.read(c))!=-1) {
String s = new String(c,0,len);
outputString.append(s);
System.out.print(s);
}
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void testFFmpeg(){
ProcessBuilder processBuilder = new ProcessBuilder();
//定义命令内容
List<String> command = new ArrayList<>();
command.add("D:\\Program Files\\ffmpeg-20180227-fa0c9d6-win64-static\\bin\\ffmpeg.exe");
command.add("-i");
command.add("E:\\ffmpeg_test\\1.avi");
command.add("-y");//覆盖输出文件
command.add("-c:v");
command.add("libx264");
command.add("-s");
command.add("1280x720");
command.add("-pix_fmt");
command.add("yuv420p");
command.add("-b:a");
command.add("63k");
command.add("-b:v");
command.add("753k");
command.add("-r");
command.add("18");
command.add("E:\\ffmpeg_test\\1.mp4");
processBuilder.command(command);
//将标准输入流和错误输入流合并,通过标准输入流读取信息
processBuilder.redirectErrorStream(true);
try {
//启动进程
Process start = processBuilder.start();
//获取输入流
InputStream inputStream = start.getInputStream();
//转成字符输入流
InputStreamReader inputStreamReader = new InputStreamReader(inputStream,"gbk");
int len = -1;
char[] c = new char[1024];
StringBuffer outputString = new StringBuffer();
//读取进程输入流中的内容
while ((len= inputStreamReader.read(c))!=-1) {
String s = new String(c,0,len);
outputString.append(s);
System.out.print(s);
}
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
我们已经准备好了工具类:
Mp4VideoUtil.java完成avi转mp4
HlsVideoUtil.java完成mp4转hls
可以直接使用。
6.1 处理流程
当视频合并成功后
- 把视频处理成m3u8流媒体
- 把视频信息写到数据库
具体代码: 在合并完成方法中调用
@Value("${xc-service-manage-media.ffmpeg-path}")
String ffmpeg_path;
?
?
private void ChangeHLS(File mergeFile, String fileMd5) {
?
// mp4 文件保存目录
String fileFolderPath = getFileFolderPath(fileMd5);
//生成的mp4的文件名称
String mp4_name = fileMd5 + ".mp4";
//生成的mp4所在的路径
String mp4folder_path = fileFolderPath;
?
?
//创建工具类对象
Mp4VideoUtil mp4VideoUtil = new Mp4VideoUtil(ffmpeg_path, mergeFile.getAbsolutePath(), mp4_name, mp4folder_path);
?
//进行处理
String result = mp4VideoUtil.generateMp4();
?
?
//4、将mp4生成m3u8和ts文件
//String ffmpeg_path, String video_path, String m3u8_name,String m3u8folder_path
//mp4视频文件路径
String mp4_video_path = mp4folder_path + mp4_name;
?
//m3u8_name文件名称
String m3u8_name = fileMd5 + ".m3u8";
//m3u8文件所在目录
String m3u8folder_path = fileFolderPath + "hls/";
?
HlsVideoUtil hlsVideoUtil = new HlsVideoUtil(ffmpeg_path, mp4_video_path, m3u8_name, m3u8folder_path);
?
//生成m3u8和ts文件
String tsResult = hlsVideoUtil.generateM3u8();
?
//保存fileUrl(此url就是视频播放的相对路径)
String filePath = fileFolderPath + "hls/" + m3u8_name;
?
?
// 将fileUrl 保存到数据库
FileMsg fileMsg = new FileMsg();
fileMsg.setFileId(fileMd5);
fileMsg.setFileName(mergeFile.getName());
fileMsg.setFilePath(filePath);
fileMsg.setFileUrl(filePath.split("C:/school/video")[1]);
?
fileMsgMapper.insert(fileMsg);
?
?
//优化: 文件处理成功后, 可以删除mp4文件
?
?
}
说明:
mp4转成m3u8如何判断转换成功?
第一、根据视频时长来判断,同mp4转换成功的判断方法。
第二、最后还要判断m3u8文件内容是否完整。
4 播放器
4.1 技术选型
视频编码后要使用播放器对其进行解码、播放视频内容。在web应用中常用的播放器有flash播放器、H5播放器或浏览器插件播放器,其中以flash和H5播放器最常见。
flash播放器:缺点是需要在客户机安装Adobe Flash Player播放器,优点是flash播放器已经很成熟了,并且浏览器对flash支持也很好。
H5播放器:基于h5自带video标签进行构建,优点是大部分浏览器支持H5,不用再安装第三方的flash播放器,并且随着前端技术的发展,h5技术会越来越成熟。
本项目采用H5播放器,使用Video.js开源播放器。
Video.js是一款基于HTML5世界的网络视频播放器。它支持HTML5和Flash视频,它支持在台式机和移动设备上播放视频。这个项目于2010年中开始,目前已在40万网站使用。
官方地址:http://videojs.com/
4.2 下载video.js
Video.js: https://github.com/videojs/video.js
videojs-contrib-hls: https://github.com/videojs/videojs-contrib-hls#installation
(videojs-contrib-hls是播放hls的一个插件)
使用文档:http://docs.videojs.com/tutorial-videojs_.html
本教程使用 video.js 6.7.3 版本,videojs-contrib-hls 5.14.1版本
将资料中提供的plugins赋值到xc-ui-pc-video项目目录下
4.3 搭建媒体服务器
正常使用video.js播放视频是通过一个网页,用户通过浏览器打开网页去播放视频,网页和视频都从web服务器请求。
4.3.1 Nginx媒体服务器
根据上边的流程,我们在媒体服务器上安装Nginx,并配置如下 :
server {
listen 81;
server_name localhost;
# 流媒体 静态资源
location ^~ /school/video/ {
alias C:/school/video/;
}
# 视频静态资源
location / {
alias C:/CODE/JAVA/school/xc-ui-pc-video/;
index index.html index.htm;
}
}
4.4 测试video.js
- 把资料中的video.html 复制到 C:/CODE/JAVA/school/xc-ui-pc-video/ 如图:
上面已经使用nginx 代理 C:/CODE/JAVA/school/xc-ui-pc-video/ 目录。 所以可以通过http请求直接访问video.html页面
- 把src路径修改为自己的媒资访问路径
- 测试:
用户打开浏览器输入 http://localhost:81/video.html 。即可打开视频播放页面,并播放。
- 上一篇:纯 Web 视频剪辑
- 下一篇:HLS视频拉流播放
相关推荐
- 网站制作的流程是什么呢?简单大概的流程
-
关注我!了解更多网站建设的小干货~如今,随着网络时代的全面到来,网站在人们的生活和工作中发挥着极其重要的作用。网站制作的发展使更多的人加入了这个行业。如果你想掌握网站制作的知识,你可以在学校或网上学习...
- 一款谷歌(Google)打造的广告网页设计制作软件
-
GoogleWebDesigner是由谷歌(Google)打造的一款广告网页设计制作软件,它能够帮助从事于广告网页设计工作或是有这方面需求的用户更加有效快速的进行完成相关的行业设计工作,软件可以支...
- 普通网站如何制作一个网站?
-
对行外人来讲,在预备做一个网站项目时,最想了解的无非就是网站制作的悉数流程。网站制作是要有计划的,事先策划好才能更快更好的完成。网站的几个基本组成元素:域名+空间+程序+模板+维护经验+日常管理.网站...
- 用纯Python就能写一个漂亮的网页,再见HTML
-
再见HTML!用纯Python就能写一个漂亮的网页我们在写一个网站或者一个网页界面的时候,需要学习很多东西,对小白来说很困难!比如我要做一个简单的网页交互:天啊,听听头都大呢!其实我就给老板做一个...
- HTML表单4(form的action、method属性)——零基础自学网页制作
-
表单的工作过程表单的信息发送与处理过程可以简单的进行图示,如下图。以注册会员为例,用户在自己的电脑上打开相应的注册表单页面填写信息,完成填写后点击提交按钮,也就是图中1所示过程。这时浏览器会将这些信息...
- 官网网站设计网页制作模板建站前端自适应响应式网站仿站门户
-
案例背景航科慧联无人机搜索雷达能够在多种天气下检测到无人机的入侵、并获得目标的距离、方向和高度等具体信息,是无人机反制作战中的关键设备。航科慧联无人机搜索雷达能够在多种天气下检测到无人机的入侵、并获得...
- 软网推荐:在线制作软件图标
-
在制作PPT演示、软件、网页或其他程序时,我们往往需要用到一些个性化的图标。现在,即便是不安装任何软件,也可以上网在线制作自己需要的图标。首先访问如下制作网址:http://www.rw-design...
- 自定义跳转的h5网页如何制作?
-
文章来源:墨鹊微站...
- 网页如何制作?这几点要知道
-
这是一个个性张扬的时代,也是一个动手能力和动脑能力都比较强的时代,因此很多人对于能够自己动手完成的东西,都不太想假手于人。于是网页制作成了各大搜索引擎里面排名比较靠前的关键词之一。想要知道网页如何制作...
- 手机端网站简单制作教程,怎么快速制作一个移动端的网站
-
想要创建一个手机端的网站,需要有域名、已经完成网站页面的开发设计,零基础朋友不懂代码技术,直接在线套用乔拓云里面的网站模板来开发是比较简单可行的,进入乔拓云网,复制网站模板编辑网站的内容,注册域名后绑...
- 几张动图教你轻松了解Dreamweaver做网页
-
施老师:当今可是互联网时代,人们的生活、社交离不开互联网,那么不管你是网页设计师,还是销售达人,还是个体户,总必不可少的要在网上呈现一些页面给客户看,这个就是让你做网页,而Dreamweaver是做网...
- 用Deepseek制作网页版的汉诺塔游戏保姆级教程
-
在deepseek中输入:“帮我做一个网页版的汉诺塔演示游戏,游戏包含2层、3层、4层、5层的汉诺塔游戏演示,制作自动求解演示按钮,点击按钮就可以生成出步数,同时自动演示最优解动画。”...
- JS制作网页版计算器
-
大家晚上好,我是洁哥,抱歉今天有点晚了,但是洁哥不会缺席哦,今天我们来看一个JS实现网页版计算器的例题,先来看一看出来的效果吧(123+123=246)(123-123=0)(123*123=1512...
- 网页制作流程哪几步
-
在数字化时代,网页制作成为企业和个人展示形象、传递信息的重要方式。但是,许多人对于网页制作的流程仍感到困扰。为了解决这一问题,我们将深入探讨网页制作的关键步骤,助您更好地理解和应用这一过程。第一步:需...
- 这4个设计技巧,教你做好个人网页制作
-
随着互联网发展,个人建站已经不是什么稀奇事,学生、求职者、插画师、摄影师、作家……都可以制作个人网站,用来展示自身形象,或者吸引粉丝。那么如何做好个人网站呢?在不懂设计和技术知识的情况下,个人网页制作...
你 发表评论:
欢迎- 一周热门
-
-
前端面试:iframe 的优缺点? iframe有那些缺点
-
带斜线的表头制作好了,如何填充内容?这几种方法你更喜欢哪个?
-
漫学笔记之PHP.ini常用的配置信息
-
其实模版网站在开发工作中很重要,推荐几个参考站给大家
-
推荐7个模板代码和其他游戏源码下载的网址
-
[干货] JAVA - JVM - 2 内存两分 [干货]+java+-+jvm+-+2+内存两分吗
-
正在学习使用python搭建自动化测试框架?这个系统包你可能会用到
-
织梦(Dedecms)建站教程 织梦建站详细步骤
-
【开源分享】2024PHP在线客服系统源码(搭建教程+终身使用)
-
2024PHP在线客服系统源码+完全开源 带详细搭建教程
-
- 最近发表
- 标签列表
-
- mybatis plus (70)
- scheduledtask (71)
- css滚动条 (60)
- java学生成绩管理系统 (59)
- 结构体数组 (69)
- databasemetadata (64)
- javastatic (68)
- jsp实用教程 (53)
- fontawesome (57)
- widget开发 (57)
- vb net教程 (62)
- hibernate 教程 (63)
- case语句 (57)
- svn连接 (74)
- directoryindex (69)
- session timeout (58)
- textbox换行 (67)
- extension_dir (64)
- linearlayout (58)
- vba高级教程 (75)
- iframe用法 (58)
- sqlparameter (59)
- trim函数 (59)
- flex布局 (63)
- contextloaderlistener (56)