ajax 비동기 로 진행 막대 영상 을 업로드 하고 미리 보기 그림 을 추출 합 니 다.
13805 단어 ajax파일 업로드진도 표미리 보기 그림 추출
서버 응답
{
"thumbnail": "/slsxpt//upload/thumbnail/fdceefc.jpg",
"success": true,
"link": "/slsxpt//upload/video/fdceefc.mp"
}
그리고 내 input file 컨트롤 이 form 태그 에 싸 이지 않 았 으 면 좋 겠 습 니 다.이 유 는 form 에 form 을 삽입 할 수 없 기 때 문 입 니 다.또한 form 라벨 은 브 라 우 저 에 약간의 기본 스타일 이 있 기 때문에 css 를 쓸 수도 있 습 니 다.이전에 ajax FileUpload 로 파일 비동기 업 로드 를 한 적 이 있 습 니 다.그러나 이 물건 은 오랫동안 업데이트 되 지 않 았 고 코드 와 bug 가 있 었 습 니 다.마지막 에 겨우 성공 적 으로 사 용 했 지만 좋 지 않 았 습 니 다.또한 ajax FileUpload 는 xhr 2 의 progress 이벤트 응답 을 직접 추가 하지 않 아 귀 찮 습 니 다.
인터넷 에서 찾 아 보 니 방법 이 매우 많다.
예 를 들 어 파일 을 업로드 한 후 업로드 진 도 를 session 에 넣 고 서버 session 에 문의 합 니 다.그러나 저 는 이 방법 에 문제 가 있다 고 생각 합 니 다.저 는 이런 방법 으로 본 진 도 는 제 서버 응용 프로그램 코드(제 것 은 action)가 서버 의 임시 디 렉 터 리 에서 파일 을 복사 하 는 진도 라 고 생각 합 니 다.모든 요청 은 서버 소프트웨어,즉 tomcat,tomcat 가 요청 에 대해 세 션,request 등 대상 을 봉인 해 야 하기 때 문 입 니 다.그리고 파일 도 실제로 받 아야 합 니 다.즉,내 action 코드 가 실행 되 기 전에 파일 이 실제로 업로드 되 었 다 는 것 이다.
나중에 jquery.form.js 플러그 인 을 사용 하 는 ajax Submit 방법 을 찾 았 습 니 다.이 방법 은 폼 으로 제출 합 니 다.즉,$.fn.ajaxsubmit.:$(form selector).ajaxsubmit({})입 니 다.이 api 의 장점 은 xhr 2 의 progress 시간 을 처리 한 것 입 니 다.호출 할 때 upload Progress 의 function 을 전달 하여 function 에서 진 도 를 얻 을 수 있 습 니 다.그리고 input file 이 form 에 싸 여 있 지 않 으 려 면 코드 에 createElement 가 있 을 수 있 습 니 다.그러나 이 방법 은 내 가 작은 실 수 를 했 기 때문에 결국 성공 하지 못 해서 애석 하 다.
ajax Submit 소스 코드
마지막 으로$.ajax 방법 으로 만 들 었 습 니 다.$..ajax 는 form 과 연결 할 필요 가 없습니다.약간 정적 인 방법 같 습 니 다.유일한 아 쉬 움 은$.ajax options 에서 progress 에 대한 응답 이 없습니다.그러나 이것 은 xhr 라 는 매개 변수 가 있 습 니 다.즉,xhr 를 맞 출 수 있 습 니 다.그러면 xhr 를 통 해 progress 의 이벤트 처리 프로그램 을 추가 할 수 있 습 니 다.ajax Submit 방법 에서 progress 사건 에 대한 처 리 를 결합 하여 보 니 갑자기 밝 아 졌 다.
그럼 저도$.ajax 방법 에 progress 이벤트 처리 함 수 를 추가 할 수 있 습 니 다.dom 에 대한 작업 을 업로드 업무 에서 추출 하기 위해 플러그 인 형식 으로 쓰기 로 했 습 니 다.다음은 플러그 인 코드 입 니 다.
;(function ($) {
var defaults = {
uploadProgress : null,
beforeSend : null,
success : null,
},
setting = {
};
var upload = function($this){
$this.parent().on('change',$this,function(event){
//var $this = $(event.target),
var formData = new FormData(),
target = event.target || event.srcElement;
//$.each(target.files, function(key, value)
//{
// console.log(key);
// formData.append(key, value);
//});
formData.append('file',target.files[]);
settings.fileType && formData.append('fileType',settings.fileType);
$.ajax({
url : $this.data('url'),
type : "POST",
data : formData,
dataType : 'json',
processData : false,
contentType : false,
cache : false,
beforeSend : function(){
//console.log('start');
if(settings.beforeSend){
settings.beforeSend();
}
},
xhr : function() {
var xhr = $.ajaxSettings.xhr();
if(xhr.upload){
xhr.upload.addEventListener('progress',function(event){
var total = event.total,
position = event.loaded || event.position,
percent = ;
if(event.lengthComputable){
percent = Math.ceil(position / total * );
}
if(settings.uploadProgress){
settings.uploadProgress(event, position, total, percent);
}
}, false);
}
return xhr;
},
success : function(data,status,jXhr){
if(settings.success){
settings.success(data);
}
},
error : function(jXhr,status,error){
if(settings.error){
settings.error(jXhr,status,error);
}
}
});
});
};
$.fn.uploadFile = function (options) {
settings = $.extend({}, defaults, options);
//
return this.each(function(){
upload($(this));
});
}
})($ || jQuery);
다음은 제 jsp 페이지 에서 이 api 를 사용 할 수 있 습 니 다.
<div class="col-sm-">
<input type="text" name="resource_url" id="resource_url" hidden="hidden"/>
<div class="progress" style='display: none;'>
<div class="progress-bar progress-bar-success uploadVideoProgress" role="progressbar"
aria-valuenow="" aria-valuemin="" aria-valuemax="" style="width: %">
</div>
</div>
<input type="file" class="form-control file inline btn btn-primary uploadInput uploadVideo"
accept="video/mp"
data-url="${baseUrl}/upload-video.action"
data-label="<i class='glyphicon glyphicon-circle-arrow-up'></i> " />
<script>
(function($){
$(document).ready(function(){
var $progress = $('.uploadVideoProgress'),
start = false;
$('input.uploadInput.uploadVideo').uploadFile({
beforeSend : function(){
$progress.parent().show();
},
uploadProgress : function(event, position, total, percent){
$progress.attr('aria-valuenow',percent);
$progress.width(percent+'%');
if(percent >= ){
$progress.parent().hide();
$progress.attr('aria-valuenow',);
$progress.width(+'%');
}
},
success : function(data){
if(data.success){
setTimeout(function(){
$('#thumbnail').attr('src',data.thumbnail);
},);
}
}
});
});
})(jQuery);
</script>
</div>
succes 에 응답 할 때 800 밀리초 초과 설정 을 한 후에 그림 을 가 져 옵 니 다.추출 축 량 도 는 다른 프로 세 스 가 응답 이 완 료 될 때 미리 보기 그림 이 추출 되 지 않 았 기 때 문 입 니 다.효 과 를 보다
축 량 도 추출
아래 부분 은 서버 에서 업 로드 를 처리 하고 동 영상 추출 축 량 도 아래 는 action 의 처리 코드 입 니 다.
package org.lyh.app.actions;
import org.apache.commons.io.FileUtils;
import org.apache.struts.ServletActionContext;
import org.lyh.app.base.BaseAction;
import org.lyh.library.SiteHelpers;
import org.lyh.library.VideoUtils;
import java.io.File;
import java.io.IOException;
import java.security.KeyStore;
import java.util.HashMap;
import java.util.Map;
/**
* Created by admin on //.
*/
public class UploadAction extends BaseAction{
private String saveBasePath;
private String imagePath;
private String videoPath;
private String audioPath;
private String thumbnailPath;
private File file;
private String fileFileName;
private String fileContentType;
// setter getter
public String video() {
Map<String, Object> dataJson = new HashMap<String, Object>();
System.out.println(file);
System.out.println(fileFileName);
System.out.println(fileContentType);
String fileExtend = fileFileName.substring(fileFileName.lastIndexOf("."));
String newFileName = SiteHelpers.md(fileFileName + file.getTotalSpace());
String typeDir = "normal";
String thumbnailName = null,thumbnailFile = null;
boolean needThumb = false,extractOk = false;
if (fileContentType.contains("video")) {
typeDir = videoPath;
//
needThumb = true;
thumbnailName = newFileName + ".jpg";
thumbnailFile
= app.getRealPath(saveBasePath + thumbnailPath) + "/" + thumbnailName;
}
String realPath = app.getRealPath(saveBasePath + typeDir);
File saveFile = new File(realPath, newFileName + fileExtend);
// ,
if (!saveFile.exists()) {
if (!saveFile.getParentFile().exists()) {
saveFile.getParentFile().mkdirs();
}
try {
FileUtils.copyFile(file, saveFile);
if(needThumb){
extractOk = VideoUtils.extractThumbnail(saveFile, thumbnailFile);
System.out.println(" :"+extractOk);
}
dataJson.put("success", true);
} catch (IOException e) {
System.out.println(e.getMessage());
dataJson.put("success", false);
}
}else{
dataJson.put("success", true);
}
if((Boolean)dataJson.get("success")){
dataJson.put("link",
app.getContextPath() + "/" + saveBasePath + typeDir + "/" + newFileName + fileExtend);
if(needThumb){
dataJson.put("thumbnail",
app.getContextPath() + "/" + saveBasePath + thumbnailPath + "/" + thumbnailName);
}
}
this.responceJson(dataJson);
return NONE;
}
}
액 션 설정
<action name="upload-*" class="uploadAction" method="{}">
<param name="saveBasePath">/upload</param>
<param name="imagePath">/images</param>
<param name="videoPath">/video</param>
<param name="audioPath">/audio</param>
<param name="thumbnailPath">/thumbnail</param>
</action>
여기 서 개인 적 으로 파일 의 이름 이 크기 와 같다 면 파일 일 확률 이 매우 높다 고 생각 합 니 다.그래서 저 는 파일 이름과 파일 크기 를 md5 로 연산 하면 같은 파일 을 중복 업로드 하 는 것 을 조금 피 할 수 있 을 것 입 니 다.코드 를 바 꿀 때 FFmpeg 을 사용 합 니 다.필요 한 건 여기 서 다운로드 할 수 있어 요.
package org.lyh.library;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/**
* Created by admin on //.
*/
public class VideoUtils {
public static final String FFMPEG_EXECUTOR = "C:/Software/ffmpeg.exe";
public static final int THUMBNAIL_WIDTH = ;
public static final int THUMBNAIL_HEIGHT = ;
public static boolean extractThumbnail(File inputFile,String thumbnailOutput){
List<String> command = new ArrayList<String>();
File ffmpegExe = new File(FFMPEG_EXECUTOR);
if(!ffmpegExe.exists()){
System.out.println(" ");
return false;
}
System.out.println(ffmpegExe.getAbsolutePath());
System.out.println(inputFile.getAbsolutePath());
command.add(ffmpegExe.getAbsolutePath());
command.add("-i");
command.add(inputFile.getAbsolutePath());
command.add("-y");
command.add("-f");
command.add("image");
command.add("-ss");
command.add("");
command.add("-t");
command.add(".");
command.add("-s");
command.add(THUMBNAIL_WIDTH+"*"+THUMBNAIL_HEIGHT);
command.add(thumbnailOutput);
ProcessBuilder builder = new ProcessBuilder();
builder.command(command);
builder.redirectErrorStream(true);
try {
long startTime = System.currentTimeMillis();
Process process = builder.start();
System.out.println(" "+(System.currentTimeMillis()-startTime));
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
}
또한 자바 에서 다른 프로 세 스 를 시 작 했 습 니 다.제 가 보기 에는 서로 상 관 없 는 것 같 습 니 다.자바 가 ffmpeg.exe 를 시작 한 후에 다음 코드 를 계속 실행 해 야 하기 때문에 따로 스 레 드 를 만들어 축 량 도 를 추출 할 필요 가 없습니다.테스트 해 보 니 시간 이 많이 걸 리 지 않 았 다.매번 긴 전송 시간 도 차이 가 크 지 않 습 니 다.다음은 같은 파일 을 두 번 업로드 하 는 데 걸 리 는 시간 입 니 다.처음
두 번 째
사용자 체험 에 있어 서 큰 차이 가 없다.
그리고 여기 큰 파일 을 업로드 하려 면 tomcat 와 struct 를 설정 해 야 합 니 다.
tomcat 아래 conf 디 렉 터 리 에 있 는 server.xml 파일 을 수정 하고 커 넥 터 노드 에 속성 maxPostSize="0"을 추가 하면 업로드 크기 를 표시 하지 않 습 니 다.
또한 struts.xml 추가 설정 을 수정 합 니 다.여기 value 단 위 는 바이트 입 니 다.여 기 는 약 300 여 mb 입 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Javascript Ajax에 대한 간단한 연습저는 약 4년 동안 프로그래밍 개인 튜터로 일한 경험이 있습니다. 약 5년 전에 " "이라는 제목의 페르시아어로 내 웹사이트에 블로그 게시물을 올렸고 사람들이 저에게 전화하기 시작했습니다. 나는 항상 사람들을 가르치...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.