web /java 实现多种格式视频上传、转码、播放、下载

1.前言

前段时间一直在做一个生物资源共享平台,采用SSM框架技术,其中涉及一个模块,是关于视频资源的播放。

本来不是很大的问题,但是无奈用户要求较多,需要支持N种格式的视频播放,没有办法,转码是必不可少的了。
对于一个从来没接触过这些什么音频视频编码格式的我,浪费了很长时间,其中很多博客的教学都不太完善。

反正就是有一堆麻烦事情,坑也多,所以我还是记录一下,以后需要的时候就不要那么麻烦了。

采用工具:

ffmpeg 软件
Mencoder 软件
Video.js 文件

废话不说了,直接上干货。

2.源码

关于上传下载就是不做重点讲了,反正代码贴出来了,直接用就行。

jsp上传页面:
add_video.jsp
实际上就是一个form表单提交请求到
action=“back/addVideo” encType=“multipart/form-data” method=“post”

源码如下:

 <div id="tab1" class="tabson"><div class="formtext">Hi,<b>${user.username}</b>,欢迎您使用教学资源共享平台!</div><form id="frm2" name="frm2" action="back/addVideo" encType="multipart/form-data" method="post"><ul class="forminfo"><li><label>资源名称<b>*</b></label><input id="title" name="title" type="text" class="dfinput" value=""  style="width:518px;"/><input id="uid" name="uid" type="text"  hidden="hidden" value="${uid}"/></li><li><label>审核状态<b>*</b></label><div class="vocation"><select class="select1" id="state" name="state"><option value="0">未审核</option><option value="1">通过</option><option value="2">不通过</option><option value="3">下架</option></select></div></li><li><label>上传者<b>*</b></label><input id="writer" name="writer" type="text" class="dfinput" value="${user.username}"  style="width:518px;"/></li><li><label>上传时间<b>*</b></label><input id="time" name="time" type="date" class="dfinput" value=""  style="width:518px;"  /></li><li><label>所属级别<b>*</b></label><div class="vocation"><select class="select1" id="grade" name="grade"><option value="0">初中</option><option value="1">高中</option></select></div></li><li><label>资源类型<b>*</b></label><div class="vocation"><select class="select1" id="subclass" name="subclass"><!-- 邹涛20180814 --><c:if test="${uid eq 3}"><option value="微视频">微视频</option><option value="实验视频">实验视频</option><option value="教学视频">教学视频</option></c:if></select></div></li><li><label>上传资源<b>*</b></label><input id="file" name="file" type="file" style="width:518px;"  /></li><li><label>点击量<b>*</b></label><input id="clicks" name="clicks" type="text" class="dfinput" value="0"  style="width:518px;"/></li>	               <li><label>&nbsp;</label><input name="" type="button" class="btn" onclick="startPost();" value="提交"/></li></ul></form></div></div>

addVideo控制层

源码如下:

					/*** @Description:(视频资源的单独上传的接收)* @param:@param request* @param:@param response* @param:@param session* @param:@return* @return:ModelAndView* @author:Zoutao* @date:2018-6-12* @version:V1.0*/@RequestMapping(value = "/addVideo")public ModelAndView uploadflie_Video(@RequestParam("file") CommonsMultipartFile file,HttpServletRequest req, HttpServletRequest request) {System.out.println("进入addVideo视频上传控制层");if (file.getSize() != 0) {//上传的多格式的视频文件-作为临时路径保存,转码以后删除-路径不能写//String path = "E:/Projectpicture/websiteimages/temp/";File TempFile = new File(path);if (TempFile.exists()) {if (TempFile.isDirectory()) {System.out.println("该文件夹存在。");}else {System.out.println("同名的文件存在,不能创建文件夹。");}}else {System.out.println("文件夹不存在,创建该文件夹。");TempFile.mkdir();}// 获取上传时候的文件名String filename = file.getOriginalFilename();// 获取文件后缀名String filename_extension = filename.substring(filename.lastIndexOf(".") + 1);System.out.println("视频的后缀名:"+filename_extension);//时间戳做新的文件名,避免中文乱码-重新生成filenamelong filename1 = new Date().getTime();filename = Long.toString(filename1)+"."+filename_extension;//去掉后缀的文件名String filename2 = filename.substring(0, filename.lastIndexOf("."));System.out.println("视频名为:"+filename2);//源视频地址+重命名后的视频名+视频后缀String yuanPATH =(path+filename);  System.out.println("视频的完整文件名1:"+filename);System.out.println("源视频路径为:"+yuanPATH);//上传到本地磁盘/服务器try {System.out.println("写入本地磁盘/服务器");InputStream is = file.getInputStream();OutputStream os = new FileOutputStream(new File(path, filename));int len = 0;byte[] buffer = new byte[2048];while ((len = is.read(buffer)) != -1) {os.write(buffer, 0, len);}os.close();os.flush();is.close();} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println("========上传完成,开始调用转码工具类=======");//调用转码机制flv mp4 f4v m3u8 webm ogg放行直接播放,//asx,asf,mpg,wmv,3gp,mov,avi,wmv9,rm,rmvb等进行其他转码为mp4if (filename_extension.equals("avi") || filename_extension.equals("rm") || filename_extension.equals("rmvb") || filename_extension.equals("wmv")|| filename_extension.equals("3gp")  || filename_extension.equals("mov")||filename_extension.equals("flv")   || filename_extension.equals("ogg")) {ConverVideoTest c = new ConverVideoTest();c.run(yuanPATH);   //调用转码System.out.println("=================转码过程彻底结束=====================");}//获取转码后的mp4文件名String Mp4path = "E://Projectpicture/websiteimages/finshvideo/";filename2 = filename2+".mp4";String NewVideopath =Mp4path +filename2;System.out.println("新视频的url:"+NewVideopath);//删除临时文件File file2 = new File(path);if (!file2.exists()) {System.out.println("没有该文件");}if (!file2.isDirectory()) {System.out.println("没有该文件夹");}String[] tempList = file2.list();File temp = null;for (int i = 0; i < tempList.length; i++) {if (path.endsWith(File.separator)) {temp = new File(path + tempList[i]);} else {temp = new File(path + File.separator + tempList[i]);}if (temp.isFile() || temp.isDirectory()) {temp.delete();		//删除文件夹里面的文件}}System.out.println("所有的临时视频文件删除成功");// 实例化用户类tb_resource resource = new tb_resource();//获取填写的相关信息String title = request.getParameter("title");String writer = request.getParameter("writer");int state = Integer.parseInt(request.getParameter("state"));String time = request.getParameter("time");int clicks = Integer.parseInt(request.getParameter("clicks"));int grade = Integer.parseInt(request.getParameter("grade"));String subclass = request.getParameter("subclass");int uid = Integer.parseInt(request.getParameter("uid"));//数据库存储信息resource.setTitle(title);resource.setWriter(writer);resource.setTime(time);resource.setClicks(clicks);resource.setGrade(grade);resource.setSubclass(subclass);resource.setState(state);resource.setUid(uid);resource.setSuffix(filename2);resource.setUrl(NewVideopath); 			//已转码后的视频存放地址// 实现对数据的更新int n = 0;n = tb_resourceService.insertResource(resource);if (n != 0) {return new ModelAndView("back/public/success").addObject("notice", "resourceList?uid=" + uid+ "&grade=-1&state=-1&subclass=" + subclass);} else {return new ModelAndView("back/public/fail").addObject("notice","resourceList?uid=" + uid+ "&grade=-1&state=-1&subclass=" + subclass);}}return null;}

其中,一开始是一个指定上传路径,然后后面是一个自动创建文件夹,防止报错。
从写入本地磁盘/服务器那里,就是采用流来上传文件。上传到指定位置。
然后 c.run(yuanPATH); 就是上传完以后调用转码机制。

各种类型的视频,最后都会统一转换为mp4格式保存下来,然后删除产生的临时文件。

后面的就是对数据的插入sql,以及页面跳转。

转码工具类:
源码如下:
Contants.java

public class Contants {/*** @Description:(3.工具类主类)设置转码工具的各个路径* @param:@param args   * @return:void  * @author:Zoutao* @date:2018-6-22* @version:V1.0*/public static final String ffmpegpath = "D:/ffmpeg/bin/ffmpeg.exe";		// ffmpeg工具安装位置public static final String mencoderpath = "D:/ffmpeg/bin/mencoder"; 	// mencoder工具安装的位置public static final String videofolder = "E://Projectpicture/websiteimages/temp/"; 	// 需要被转换格式的视频目录public static final String videoRealPath = "E://Projectpicture/websiteimages/temp/"; 	// 需要被截图的视频目录public static final String targetfolder = "E://Projectpicture/websiteimages/finshvideo/"; // 转码后视频保存的目录public static final String imageRealPath = "E://Projectpicture/websiteimages/finshimg/"; // 截图的存放目录}

这是指定源视频上传的位置,临时视频产生的位置,转码以后的位置,视频截图的存放位置,以及两个工具的安装位置。

ConverVideoTest.java
源码如下:

package com.resource.mytools;
public class ConverVideoTest {/*** @Description:(1.转码和截图功能调用)* @param:@param yuanPATH   * @return:void  * @author:Zoutao* @date:2018-6-23* @version:V1.0*//*本地测试专用--zoutao*/public static void main(String[] args) {ConverVideoTest c = new ConverVideoTest();String yuanPATH = "D:/testfile/video/短avi测试.avi";  //本地源视频c.run(yuanPATH);}//web调用public void run(String yuanPATH) {try {// 转码和截图功能开始//String filePath = "D:/testfile/video/rmTest.rm";  //本地源视频测试String filePath = yuanPATH;				//web传入的源视频System.out.println("ConverVideoTest说:传入工具类的源视频为:"+filePath);ConverVideoUtils zout = new ConverVideoUtils(filePath);  //传入pathString targetExtension = ".mp4";  				//设置转换的格式boolean isDelSourseFile = true;//删除源文件boolean beginConver = zout.beginConver(targetExtension,isDelSourseFile);System.out.println(beginConver);} catch (Exception e) {e.printStackTrace();}}
}

这是用来指定转码的视频格式,调用转码工具类。

ConverVideoUtils.java
源码如下:

package com.resource.mytools;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;/*** 
* @Title: ConverVideoUtils.java
* @Package:com.resource.mytools
* @Description:(2.转码和截图功能)
* @see:接收Contants实体的路径
* @author:Zoutao 
* @date:2018-7-15
* @version:V1.0*/public class ConverVideoUtils {private String sourceVideoPath;							//源视频路径private String filerealname;				 			//文件名不包括后缀名private String filename; 								//包括后缀名private String videofolder = Contants.videofolder; 		// 别的格式视频的目录private String targetfolder = Contants.targetfolder; 	// flv视频的目录private String ffmpegpath = Contants.ffmpegpath;		 // ffmpeg.exe的目录private String mencoderpath = Contants.mencoderpath; 	// mencoder的目录private String imageRealPath = Contants.imageRealPath;   // 截图的存放目录public ConverVideoUtils() {}//重构构造方法,传入源视频public ConverVideoUtils(String path) {sourceVideoPath = path;}//set和get方法传递pathpublic String getPATH() {return sourceVideoPath;}public void setPATH(String path) {sourceVideoPath = path;}/*** 转换视频格式* @param String targetExtension 目标视频后缀名 .xxx* @param boolean isDelSourseFile 转换完成后是否删除源文件* @return*/public boolean beginConver(String targetExtension, boolean isDelSourseFile) {File fi = new File(sourceVideoPath);filename = fi.getName();      		 //获取文件名+后缀名filerealname = filename.substring(0, filename.lastIndexOf(".")); //获取不带后缀的文件名-后面加.toLowerCase()小写System.out.println("----接收到文件("+sourceVideoPath+")需要转换-------");//检测本地是否存在/*if (checkfile(sourceVideoPath)) {System.out.println(sourceVideoPath + "========该文件存在哟 ");return false;}*/System.out.println("----开始转文件(" + sourceVideoPath + ")-------------------------- ");//执行转码机制if (process(targetExtension,isDelSourseFile)) {System.out.println("视频转码结束,开始截图================= ");//视频转码完成,调用截图功能--zoutaoif (processImg(sourceVideoPath)) {System.out.println("截图成功! ");} else {System.out.println("截图失败! ");}//删除原视频+临时视频/*if (isDelSourseFile) {deleteFile(sourceVideoPath);}*//*File file1 = new File(sourceVideoPath); if (file1.exists()){System.out.println("删除原文件-可用:"+sourceVideoPath);file1.delete();}*/String temppath=videofolder + filerealname + ".avi";File file2 = new File(temppath); if (file2.exists()){System.out.println("删除临时文件:"+temppath);file2.delete();}	sourceVideoPath = null;return true;} else {sourceVideoPath = null;return false;}}/*** 检查文件是否存在-多处都有判断* @param path* @return*//*private boolean checkfile(String path) {path = sourceVideoPath;File file = new File(path);try {if (file.exists()) {System.out.println("视频文件不存在============="+path);return true;} else {System.out.println("视频文件存在"+path);return false;}} catch (Exception e) {// TODO: handle exceptionSystem.out.println("拒绝对文件进行读访问");}return false;}*//*** 视频截图功能* @param sourceVideoPath 需要被截图的视频路径(包含文件名和后缀名)* @return*/public boolean processImg(String sourceVideoPath) {//先确保保存截图的文件夹存在File TempFile = new File(imageRealPath);if (TempFile.exists()) {if (TempFile.isDirectory()) {System.out.println("该文件夹存在。");}else {System.out.println("同名的文件存在,不能创建文件夹。");}}else {System.out.println("文件夹不存在,创建该文件夹。");TempFile.mkdir();}File fi = new File(sourceVideoPath);filename = fi.getName();			//获取视频文件的名称。filerealname = filename.substring(0, filename.lastIndexOf("."));	//获取视频名+不加后缀名 后面加.toLowerCase()转为小写List<String> commend = new ArrayList<String>();//第一帧: 00:00:01 //截图命令:time ffmpeg -ss 00:00:01 -i test1.flv -f image2 -y test1.jpgcommend.add(ffmpegpath);			//指定ffmpeg工具的路径commend.add("-ss");commend.add("00:00:01");			//1是代表第1秒的时候截图commend.add("-i");commend.add(sourceVideoPath);		//截图的视频路径commend.add("-f");commend.add("image2");commend.add("-y");commend.add(imageRealPath + filerealname + ".jpg");		//生成截图xxx.jpg//打印截图命令--zoutaoStringBuffer test = new StringBuffer();    for (int i = 0; i < commend.size(); i++) {    test.append(commend.get(i) + " ");    }    System.out.println("截图命令:"+test);    //转码后完成截图功能-还是得用线程来解决--zoutaotry {			/*ProcessBuilder builder = new ProcessBuilder();builder.command(commend);Process p =builder.start();*///调用线程处理命令ProcessBuilder builder = new ProcessBuilder();builder.command(commend);Process p = builder.start(); //获取进程的标准输入流  final InputStream is1 = p.getInputStream();   //获取进程的错误流  final InputStream is2 = p.getErrorStream(); //启动两个线程,一个线程负责读标准输出流,另一个负责读标准错误流  new Thread() {    public void run() {    BufferedReader br = new BufferedReader(    new InputStreamReader(is1));    try {    String lineB = null;    while ((lineB = br.readLine()) != null) {    if (lineB != null){    //System.out.println(lineB);    //必须取走线程信息避免堵塞}}    } catch (IOException e) {    e.printStackTrace();    } //关闭流finally{  try {  is1.close();  } catch (IOException e) {  e.printStackTrace();  }  }  }    }.start();    new Thread() {    public void run() {    BufferedReader br2 = new BufferedReader(    new InputStreamReader(is2));    try {    String lineC = null;    while ((lineC = br2.readLine()) != null) {    if (lineC != null)   { //System.out.println(lineC);   //必须取走线程信息避免堵塞}}    } catch (IOException e) {e.printStackTrace();  }  //关闭流finally{  try {  is2.close();  } catch (IOException e) {  e.printStackTrace();  }  } }    }.start();   // 等Mencoder进程转换结束,再调用ffmepg进程非常重要!!!p.waitFor();System.out.println("截图进程结束");return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 实际转换视频格式的方法* @param targetExtension 目标视频后缀名* @param isDelSourseFile 转换完成后是否删除源文件* @return*/private boolean process(String targetExtension, boolean isDelSourseFile) {//先判断视频的类型-返回状态码int type = checkContentType();  boolean status = false;//根据状态码处理if (type == 0) {System.out.println("ffmpeg可以转换,统一转为mp4文件");status = processVideoFormat(sourceVideoPath,targetExtension,isDelSourseFile);//可以指定转换为什么格式的视频} else if (type == 1) {//如果type为1,将其他文件先转换为avi,然后在用ffmpeg转换为指定格式System.out.println("ffmpeg不可以转换,先调用mencoder转码avi");String avifilepath = processAVI(type);if (avifilepath == null){// 转码失败--avi文件没有得到System.out.println("mencoder转码失败,未生成AVI文件");return false;}else {System.out.println("生成AVI文件成功,ffmpeg开始转码:");status = processVideoFormat(avifilepath,targetExtension,isDelSourseFile);}}return status;   //执行完成返回布尔类型true}/*** 检查文件类型* @return*/private int checkContentType() {//取得视频后缀-String type = sourceVideoPath.substring(sourceVideoPath.lastIndexOf(".") + 1, sourceVideoPath.length()).toLowerCase();System.out.println("源视频类型为:"+type);// 如果是ffmpeg能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv等)if (type.equals("avi")) {return 0;} else if (type.equals("mpg")) {return 0;} else if (type.equals("wmv")) {return 0;} else if (type.equals("3gp")) {return 0;} else if (type.equals("mov")) {return 0;} else if (type.equals("mp4")) {return 0;} else if (type.equals("asf")) {return 0;} else if (type.equals("asx")) {return 0;} else if (type.equals("flv")) {return 0;}else if (type.equals("mkv")) {return 0;}// 如果是ffmpeg无法解析的文件格式(wmv9,rm,rmvb等),  // 就先用别的工具(mencoder)转换为avi(ffmpeg能解析的)格式.  else if (type.equals("wmv9")) {return 1;} else if (type.equals("rm")) {return 1;} else if (type.equals("rmvb")) {return 1;}System.out.println("上传视频格式异常");return 9;}/***  对ffmpeg无法解析的文件格式(wmv9,rm,rmvb等), *  可以先用(mencoder)转换为avi(ffmpeg能解析的)格式.再用ffmpeg解析为指定格式* @param type* @return*/private String processAVI(int type) {System.out.println("调用了mencoder.exe工具");List<String> commend = new ArrayList<String>();commend.add(mencoderpath);                //指定mencoder.exe工具的位置commend.add(sourceVideoPath);             //指定源视频的位置commend.add("-oac");commend.add("mp3lame");			//lavc 原mp3lamecommend.add("-lameopts");commend.add("preset=64");commend.add("-ovc");commend.add("xvid"); 		//mpg4(xvid),AVC(h.264/x264),只有h264才是公认的MP4标准编码,如果ck播放不了,就来调整这里commend.add("-xvidencopts");  //xvidencopts或x264encopts commend.add("bitrate=600");		//600或440commend.add("-of");commend.add("avi");commend.add("-o");commend.add(videofolder + filerealname + ".avi");   //存放路径+名称,生成.avi视频//打印出转换命令-zoutaoStringBuffer test = new StringBuffer();    for (int i = 0; i < commend.size(); i++) {    test.append(commend.get(i) + " ");    }System.out.println("mencoder输入的命令:"+test);// cmd命令:mencoder 1.rmvb -oac mp3lame -lameopts preset=64 -ovc xvid// -xvidencopts bitrate=600 -of avi -o rmvb.avitry {//调用线程命令启动转码ProcessBuilder builder = new ProcessBuilder();builder.command(commend);Process p = builder.start();   //多线程处理加快速度-解决数据丢失//doWaitFor(p);//获取进程的标准输入流  final InputStream is1 = p.getInputStream();   //获取进程的错误流  final InputStream is2 = p.getErrorStream(); //启动两个线程,一个线程负责读标准输出流,另一个负责读标准错误流  new Thread() {    public void run() {    BufferedReader br = new BufferedReader(    new InputStreamReader(is1));    try {    String lineB = null;    while ((lineB = br.readLine()) != null) {    if (lineB != null){    System.out.println(lineB);    //打印mencoder转换过程代码-可注释}}    } catch (IOException e) {    e.printStackTrace();    } //关闭流/* finally{  try {  is1.close();  } catch (IOException e) {  e.printStackTrace();  }  }  */}    }.start();    new Thread() {    public void run() {    BufferedReader br2 = new BufferedReader(    new InputStreamReader(is2));    try {    String lineC = null;    while ((lineC = br2.readLine()) != null) {    if (lineC != null)   { System.out.println(lineC);    //打印mencoder转换过程代码}}    } catch (IOException e) {e.printStackTrace();  }  //关闭/* finally{  try {  is2.close();  } catch (IOException e) {  e.printStackTrace();  }  } */ }    }.start();   // 等Mencoder进程转换结束,再调用ffmepg进程非常重要!!!p.waitFor();System.out.println("Mencoder进程结束");  return videofolder + filerealname + ".avi";		//返回转为AVI以后的视频地址} catch (Exception e) {e.printStackTrace();return null;}}/*** 转换为指定格式--zoutao* ffmpeg能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv等)* @param oldfilepath* @param targetExtension 目标格式后缀名 .xxx* @param isDelSourseFile 转换完成后是否删除源文件* @return*/private boolean processVideoFormat(String oldfilepath, String targetExtension, boolean isDelSourceFile) {System.out.println("调用了ffmpeg.exe工具");//先确保保存转码后的视频的文件夹存在File TempFile = new File(targetfolder);if (TempFile.exists()) {if (TempFile.isDirectory()) {System.out.println("该文件夹存在。");}else {System.out.println("同名的文件存在,不能创建文件夹。");}}else {System.out.println("文件夹不存在,创建该文件夹。");TempFile.mkdir();}List<String> commend = new ArrayList<String>();commend.add(ffmpegpath);		 //ffmpeg.exe工具地址commend.add("-i");commend.add(oldfilepath);			//源视频路径commend.add("-vcodec");  commend.add("h263");  //commend.add("-ab");		//新增4条commend.add("128");      //高品质:128 低品质:64commend.add("-acodec");		commend.add("mp3");      //音频编码器:原libmp3lamecommend.add("-ac");     commend.add("2");       //原1 commend.add("-ar");commend.add("22050");   //音频采样率22.05kHzcommend.add("-r"); commend.add("29.97");  //高品质:29.97 低品质:15commend.add("-c:v");commend.add("libx264");	//视频编码器:视频是h.264编码格式commend.add("-strict");commend.add("-2");commend.add(targetfolder + filerealname + targetExtension);  // //转码后的路径+名称,是指定后缀的视频//打印命令--zoutaoStringBuffer test = new StringBuffer();    for (int i = 0; i < commend.size(); i++) {    test.append(commend.get(i) + " ");    }System.out.println("ffmpeg输入的命令:"+test);try {//多线程处理加快速度-解决rmvb数据丢失builder名称要相同ProcessBuilder builder = new ProcessBuilder();builder.command(commend);Process p = builder.start();   //多线程处理加快速度-解决数据丢失final InputStream is1 = p.getInputStream();final InputStream is2 = p.getErrorStream();new Thread() {    public void run() {    BufferedReader br = new BufferedReader(    new InputStreamReader(is1));    try {    String lineB = null;    while ((lineB = br.readLine()) != null) {    if (lineB != null)    System.out.println(lineB);    //打印mencoder转换过程代码}    } catch (IOException e) {    e.printStackTrace();    }    }    }.start();    new Thread() {    public void run() {    BufferedReader br2 = new BufferedReader(    new InputStreamReader(is2));    try {    String lineC = null;    while ((lineC = br2.readLine()) != null) {    if (lineC != null)    System.out.println(lineC);    //打印mencoder转换过程代码}    } catch (IOException e) {e.printStackTrace();  }    }}.start();	 p.waitFor();		//进程等待机制,必须要有,否则不生成mp4!!!System.out.println("生成mp4视频为:"+videofolder + filerealname + ".mp4");return true;} catch (Exception e) {e.printStackTrace();return false;}}
}

这个文件就有些复杂了,其中涉及到视频的转码、截图、转码是需要判断视频类型的,

如果是ffmpeg能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv等)就用ffmpeg转码成mp4。

如果是ffmpeg无法解析的文件格式(wmv9,rm,rmvb等), 就先用别的工具(mencoder)转换为avi,然后在采用ffmpeg来转码成mp4。

每个视频还会自动生成一张相关的图片。用于前台展示。
其中视频是转码成h.264的编码格式,很多播放器对这个有要求。

这样以后,等web上传一个视频,就会上传,然后转码成mp4,然后数据记录存入sql中。

上传的视频:
这里写图片描述

转码以后的视频:
这里写图片描述

转码后生成的视频截图:
这里写图片描述

在前台做个a标签,附带参数id,当点击视频的对应id以后,就会跳转到videoView视频播放页控制层,查询数据,然后拿到url,然后跳转到播放页面去。

videoView控制层
源码如下:

					/*** @Description:(跳转到后台视频的播放页)* @param:@param request* @param:@param response* @param:@param session* @param:@return* @return:ModelAndView* @author:Zoutao* @date:2018-6-12* @version:V1.0*/@RequestMapping("/videoView")public ModelAndView videoView(HttpServletRequest request,HttpServletResponse response, HttpSession session) {System.out.println("进入videoView视频播放页控制层");ModelAndView model = new ModelAndView("back/playvideo");// 获取上传的idint id = Integer.parseInt(request.getParameter("id"));tb_resource resource = null;resource = tb_resourceService.getResourceById(id); // 通过id获取资源信息System.out.println("查询到的数据:" + resource);String url = resource.getUrl();System.out.println("地址为:" + url);System.out.println("获取文件名filename");String suffix = resource.getSuffix();System.out.println("后缀名为:" + suffix);System.out.println("播放的视频路径:" + url);// 调用转换类DocConverter,并将需要转换的文件传递给该类的构造方法session.setAttribute("VideoName", suffix);	//只需要把文件名字/后缀名注入到session带回前台System.out.println("全局路径为:" + session.getAttribute("VideoName"));if (resource!=null) {model.addObject("resource",resource); //视频相关信息带到前台}return model;}

前台的视频播放页面:
播放器采用video.js插件,因为视频都已经转码成mp4的了,就不在乎原来是什么格式的,任何一个播放器基本上都可以播放mp4.

源码如下:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<%String path = request.getContextPath();String basePath = request.getScheme() + "://"+ request.getServerName() + ":" + request.getServerPort()+ path + "/";
%>
<%String VideoName = session.getAttribute("VideoName").toString();
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<base href="<%=basePath%>">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link href="css/backstyle.css" rel="stylesheet" type="text/css" />
<link href="css/select.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="<%=basePath%>js/jquery.js"></script>
<script type="text/javascript" src="js/jquery.idTabs.min.js"></script>
<script type="text/javascript" src="js/select-ui.min.js"></script><!-- 去掉...引用就是使用video.js播放,不引用就是使用html5的video标签播放 -->
<script src="<%=basePath%>static.../js/video.min.js"></script>
<script src="<%=basePath%>static.../js/zh-CN.js"></script>
<link href="<%=basePath%>static.../css/video-js.min.css" rel="stylesheet"><script>videojs.options.flash.swf = "http://example.com/path/to/video-js.swf"
</script><style>
body {background-color: #e5ebeewidth: 1000px;height: 800px;
}.m { width: 600px;height: 400px;margin-left: 20%;margin-right: 5%;margin-top: 2%;margin-bootom: 5%;
}/* 暂停时显示播放按钮 */
.vjs-paused .vjs-big-play-button,
.vjs-paused.vjs-has-started .vjs-big-play-button {display: block;
}/* 点击屏幕播放/暂停 */
.video-js.vjs-playing .vjs-tech {pointer-events: auto;
}
</style><!-- 设置宽高自适应 -->
<script type="text/javascript">
var player = videojs('#my-video',{fluid: true},function(){console.log('Good to go!');this.play(); // if you don't trust autoplay for some reason
})videojs("my-video", {}, function(){//video.js初始化完成后执行});</script><title>视频播放</title>
</head>
<body><div class="place"><span>位置:</span><ul class="placeul"><!-- <li><a href="back/resourceList?uid=3">视频资源管理</a></li> --><li><a href="javascript:void(0)">视频播放</a></li></ul></div><div class="Name" style="font-size: 15px;margin: 1% 0 0 0;text-align: center;"><%-- 视频名称:<%=VideoName%> --%><c:if test="${not empty resource}"><td>视频标题:${resource.title}</td><td>上传者:${resource.writer}</td><td>上传时间:${resource.time}</td><td>播放量:${resource.clicks}</td></c:if> </div><!-- class后面加vjs-fluid就设置宽高自适应 ,浏览器自带的控制条,自动预加载,视频封面--><div class="m"><video id="my-video" class="video-js vjs-big-play-centered" width="800" height="500" align="middle" controls="true" preload="auto" poster="/websiteimages/finshimg/GZNC.jpg" data-setup="{}" ><source src="/websiteimages/finshvideo/<%=VideoName%>" type="video/mp4" ></source><p class="vjs-no-js">暂不支持本浏览器 <a href="http://videojs.com/html5-video-support/"target="_blank">请将浏览器设置为极速模式,使用html5播放</a></p></video><p style="color:red;margin:20px auto auto 33%;">温馨提示:点击播放器中下载按钮或者鼠标右键另存视频即可下载本视频。</p>
</div> <!--这是带下载按钮版本--><!-- <video id="my-video" class="video-js " src="/video/5.mp4" controls="controls"			//浏览器自带的控制条preload="auto"width="500"			//不能写pxheight="300" poster="/video/1.jpg" >		//视频封面您的浏览器不支持播放该视频!</video> -->
</body>
</html>

其中/websiteimages,是tomcat虚拟路径,配置的是

<Context docBase="D:\testfile\video\" path="/websiteimages" reloadable="true"/>

src="/websiteimages/finshvideo/<%=VideoName%>" 就是表示播放的是该路径下的某个指定名称的视频文件。

下载视频
源码代码:

				/*** @author:zoutao* @comments(方法的说明):后台各类资源下载+视频下载* @time 2018年05月24日* @returnType:String*/@RequestMapping("/downloadfile")public String Download(HttpServletRequest request,HttpServletResponse response) {response.setCharacterEncoding("utf-8");response.setContentType("text/html;charset=utf-8");response.setContentType("multipart/form-data");String url = request.getParameter("url");String fileName= url.substring(url.lastIndexOf('/')+1);//		System.out.println(fileName);response.setHeader("Content-Disposition", "attachment;fileName="+ fileName);// 获取文件后缀名-通过后缀来判断是不是视频类的String filename_extension = fileName.substring(fileName.lastIndexOf(".") + 1);System.out.println("视频的后缀名:"+filename_extension);String path="";try {if (filename_extension.equals("mp4") || filename_extension=="mp4" || filename_extension.equals("MP4") || filename_extension=="MP4") {path ="E://Projectpicture/websiteimages/finshvideo/"; //视频文件的位置}else {path = "E://Projectpicture/websiteimages/"; 	//其他文件的位置}InputStream inputStream = new FileInputStream(new File(path+ fileName));System.out.println(path+ fileName);OutputStream os = response.getOutputStream();byte[] b = new byte[2048];int length;while ((length = inputStream.read(b)) > 0) {os.write(b, 0, length);}os.close();inputStream.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}//  返回值要注意,要不然就出现下面这句错误!//java+getOutputStream() has already been called for this responsereturn null;}

也是采用流的方式来下载即可。只需要找对文件存储的位置,这样就可以直接下载。

最终效果:

前台,点击相关的图片,跳转到视频播放页面
这里写图片描述

播放视频:
这里写图片描述

点击下载:
这里写图片描述

后台查询数据:
这里写图片描述

播放视频和下载视频跟前台一样。

上传视频:(QQ不是我的)
这里写图片描述

这个就是一整个关于web/java实现多种格式视频上传、转码、播放、下载等功能,主要的方法已经在文中给出,只需要根据参数,提供参数即可调用。

需要源码的话,可以留下邮箱。


You got a dream, you gotta protect it.
如果你有梦想的话,就要去捍卫它 。 ——《当幸福来敲门》

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. DedeCMS group.php SQL注入漏洞

    DedeCMS group.php SQL注入漏洞WASC Threat Classification 描述: 目标存在SQL注入漏洞。 1.SQL注入攻击就是攻击者通过欺骗数据库服务器执行非授权的任意查询过程。 2.DedeCMS存在对URL中的参数未作任何过滤,导致SQL注入漏洞。3.在group/global.inc.php中, $db->SetQuer…...

    2024/4/17 19:09:34
  2. 学习的榜样

    90后的代码界“女神”李雪:在编程中找到自己的“灵魂”发表于2013-07-23 12:18| 126346次阅读| 来源CSDN| 274 条评论|作者王鹏编程之美微软李雪ACM职场程序人生社区之星摘要:在第二届微软“编程之美全国挑战赛”中,来自北京邮电大学的大三女生李雪以复赛以及决赛的优秀表现…...

    2024/4/18 14:59:12
  3. 墨者 - SQL注入漏洞测试(HTTP头注入)

    手动判断注入点判断字段判断表名union select 1,2,3,(select group_concat(table_name) from information_schema.tables where table_schema=database())判断列名 union select 1,2,3,(select group_concat(column_name) from information_schema.columns where table_name=fl…...

    2024/4/18 17:03:11
  4. Tomcat配置HTTPS协议的过程

    最近要写一个微信小程序,现在要将前端与后台连通起来。但是微信小程序只支持https协议,而Tomcat默认http协议。所以在这里需要给Tomcat配置https协议。然而在看过很多的教程后并尝试了很多遍,总是出现问题,感觉每个教程似乎都不完整。因此为了不让此次的努力在时间里消散。…...

    2024/4/17 19:09:16
  5. 【轻松一刻】Java制作字符动画

    前言 今晚闲来无事,整理了一下电脑中尘封已久的旧代码,看着那些年自己写过的代码,踩过的坑,顿时老泪纵横。正当在感叹之际,突然发现在“马克思”文件夹下出现了一个好玩的项目,那就是N年前刚学Java时写的GIF转字符动画的小玩具,虽然是个小玩意,但是在当时能搞点东西出来…...

    2024/4/19 14:40:21
  6. IntelliJ IDEA Tomcat配置 详解

    1> 进入 Edit Configurations2> 点击 + ,选择 Tomcat 服务器,如果是本地Tomcat 选择 Local3> Tomcat Server -> Unnamed -> Server -> Application server 的 Configuration ,找到本地 Tomcat 服务器,再点击 OK按钮4> 1 所示,我们可以切换随时为项目…...

    2024/4/17 19:09:23
  7. Unity 2D独立开发手记(外篇):Anima2D动画制作

    角色全都是用手机的dotpict这款像素画APP一点一点画出来的,没啥艺术细胞也不懂什么解剖学,人体比例什么的,先乱画了一个角色练练手吧,制作动画要用的。虽说也是像素风的,跟其他现有的像素风游戏差得不是一点半点_(:з」∠)_动画制作我使用的是Asset Store里面的Anima2D插件…...

    2024/4/17 23:51:23
  8. zzcmsV8.2之SQL注入漏洞审计

    1、漏洞发现:发现注入点存在/user/del.php文件下。注入点存在于第141行(142为自己添加的测试代码),注入参数为tablename,此处tablename接收时未经过任何安全检查。可见,只对$id进行了安全检查。2、漏洞验证:首先,通篇阅读del.php文件,掌握逻辑结构,发现主要针对table…...

    2024/4/17 19:09:16
  9. 马士兵 java视频链接

    链接:http://www.verycd.com/topics/93279/...

    2024/4/17 19:09:10
  10. 再谈Docker,微服务的场景化应用

    看过《超能陆战队》的朋友可能仍然对于电影中的男主角介绍和演示自己发明的微型机器人的场景记忆犹新。 “它”看起来只是一跟带有磁性的小小的金属部件。但是它是一个独立的个体,自己能够独立的大脑,同时,和同伴之间有相互的接口你行链接。能够通讯。能够随意的组合成任意功…...

    2024/4/19 11:27:09
  11. MyEclipse+Tomcat配置详解

    (尊重劳动成果,转载请注明出处:http://blog.csdn.NET/qq_25827845/article/details/53982209 冷血之心的博客)关注微信公众号(文强的技术小屋),学习更多技术知识,一起遨游知识海洋~目录一、Tomcat1 Tomcat概述2 安装、启动、配置Tomcat2.1 Tomcat目录结构2.2 启动和…...

    2024/4/17 19:10:35
  12. 利用SQL注入漏洞登录后台的实例

    转载: http://www.php100.com/html/webkaifa/PHP/PHPyingyong/2012/0210/9803.html在开发网站的时候,出于安全考虑,需要过滤从页面传递过来的字符。通常,用户可以通过以下接口调用数据库的内容:URL地址栏、登陆界面、留言板、搜索框等。这往往给骇客留下了可乘之机。轻则…...

    2024/4/17 19:11:40
  13. 理解顶点着色器和像素着色器

    首先,看一下通用着色器原理图:再看一下可编程图形管道描述了 图形 内容呈现的方式(参见图1)。图1. 可编程图形管道结构图。查看上图,留意顶点着色器和片段着色器是如何构成管道中的重要部分的。 当呈现一个几何形状时,您将有一个称为 VertexBuffer 的顶点流,它生成几何三…...

    2024/4/24 14:55:05
  14. Tomcat配置本地文件【图片】服务器

    人工智能,零基础入门!http://www.captainbed.net/inner一、简介一般情况下,我们项目开发时,在本地环境下,把这个tomcat作为项目服务器,就是把项目放在tomcat上面跑。这个是tomcat用的最多的地方,分享一下,但是其实Tomcat还可以作为其他来用,这里要讲的就是用tomcat来配…...

    2024/3/28 21:59:02
  15. 由浅入深的最全的比特币区块链概念、原理和应用场景

    2018-01-01 黄锦 光谷猫友会2017年全球数字货币总市值一度超过6000亿美金,Google发布的年度热搜榜,比特币在“全球新闻”类别排名第二。比特币和区块链技术非常火,最近我在研究区块链溯源跟美玉秀秀以及珠宝玉石鉴定的结合,所以系统的研究了一下区块链技术, 希望能帮小白…...

    2024/4/28 23:56:49
  16. 防SQL注入漏洞函数集

    1、 SQL注入漏洞可谓是“千里之堤,溃于蚁穴”,这种漏洞在网上极为普遍,通常是由于程序员对注入不了解,或者程序过滤不严格,或者某个参数忘记检查导致。在这里,我给大家一个函数,代替ASP中的Request函数,可以对一切的SQL注入Say NO,函数如下: Function SafeRequest(…...

    2024/4/20 5:21:03
  17. 对抗生成网络(Generative Adversarial Network)

    本课程是针对李宏毅教授在Youtube上上传的机器学习课程视频《Introduction of Generative Adversarial Network (GAN)》的学习笔记。课程视频地址Introduction Outline Basic Idea of GAN When do we need GAN GAN as structured learning algorithm 问题一为什么生成器不自己学…...

    2024/4/18 8:28:43
  18. Tomcat服务器安装配置部署

    首先下载tomcat服务器:tomcat是一个免费开源的服务器,可以到官方网站:http://tomcat.apache.org/下载,jdk每更新一个版本,tomcat就会推出响应版本与之对应。截止到现在,最低可用版本是tomcat7。官方提供解压版和安装版,解压版提供32位/64位,有一些小的区别是32位的是可…...

    2024/4/20 4:23:26
  19. 安恒月赛——四月春季站(misc、crypto)

    写在前面: 小菜鸡又来写博客了 啊啊啊啊啊小菜鸡又被虐了一遍,好疼啊[/心疼的抱住自己.jpg] [/被自己菜哭.jpg] 不过还是要继续学习啊!!!!冲冲冲!!!! misc 0x016G还远吗(签到题) 开始点击下载后发现文件接近1G,而且速度贼慢,上面显示下完需要14天╭(╯^╰)╮(不…...

    2024/4/17 19:10:18
  20. Vulhub漏洞复现之ThinkPHP5.X SQL注入漏洞和敏感信息泄露漏洞

    我是啊锋,一个努力的学渣,作为一个刚进入安全大门的小白,我希望能把自己所学到的东西总结出来,分享到博客上,可以一起进步,一起交流,一起学习。前文: 名字雷同但差个n的两种类型漏洞环境靶机:vulnhub与vulhub的区别 Vulhub漏洞复现之Dns域传送漏洞 Vulhub漏洞复现之Dj…...

    2024/4/19 11:55:04

最新文章

  1. 从0开始linux(1)——文件操作

    欢迎来到博主的专栏——从0开始linux 博主ID&#xff1a;代码小豪 博主使用的linux发行版是&#xff1a;CentOS 7.6 不同版本下的操作可能存在差异 文章目录 命令文件操作命令文件树和文件路径文件树绝对路径相对路径 文件属性tree指令删除文件复制文件 大家还记得在小学第一次…...

    2024/5/5 12:02:40
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. 线程池的方式爬虫

    <!--爬虫仅支持1.8版本的jdk--> <!-- 爬虫需要的依赖--> <dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.2</version> </dependency><!-- 爬虫需…...

    2024/5/3 23:35:40
  4. 产品推荐 | 中科亿海微推出亿迅®A8000金融FPGA加速卡

    01、产品概述 亿迅A8000金融加速卡&#xff0c;是中科亿海微联合金融证券领域的战略合作伙伴北京睿智融科&#xff0c;将可编程逻辑芯片与金融行业深度结合&#xff0c;通过可编程逻辑芯片对交易行情加速解码&#xff0c;实现低至纳秒级的解码引擎&#xff0c;端到端的处理时延…...

    2024/5/5 8:49:23
  5. 实现窗口拖拽移动

    import Vue from "vue"; /* * 定义公共js里&#xff0c;在入口文件main.js中import&#xff1b; * 给elementUI的dialog上加上 v-dialogDrag 指令就可以实现弹窗的全屏和拉伸了。 */ // v-dialogDrag: 弹窗拖拽水平方向伸缩 Vue.directive(dialogDrag, { bind(e…...

    2024/5/4 10:53:59
  6. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/5/4 23:54:56
  7. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/5/4 23:54:56
  8. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/5/4 23:54:56
  9. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/5/4 23:55:17
  10. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/5/4 23:54:56
  11. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/5/4 23:55:05
  12. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/5/4 23:54:56
  13. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/5/4 23:55:16
  14. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/5/4 23:54:56
  15. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/5/4 18:20:48
  16. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/5/4 23:54:56
  17. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/5/4 23:55:17
  18. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/5/4 23:55:06
  19. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/5/4 23:54:56
  20. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/5/4 23:55:06
  21. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/5/5 8:13:33
  22. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/5/4 23:55:16
  23. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/5/4 23:54:58
  24. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/5/4 23:55:01
  25. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/5/4 23:54:56
  26. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  27. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  28. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  29. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  30. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  31. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  32. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  33. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  34. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  35. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  36. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  37. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  38. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  39. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  40. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  41. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  42. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  43. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  44. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  45. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57