diff --git a/pom.xml b/pom.xml index 1f7db1a..afe0949 100644 --- a/pom.xml +++ b/pom.xml @@ -4,33 +4,33 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.github.dadiyang + com.github.zywayh jave jar - 1.0.6 + 1.0.7 org.sonatype.oss oss-parent 9 - - - GNU General Public License (GPL) - http://www.gnu.org/licenses/gpl.txt - - - - https://github.com/dadiyang/jave - https://github.com/dadiyang/jave.git - https://github.com/dadiyang/jave - - - - Xuyang Huang - dadiyang@aliyun.com - https://github.com/dadiyang/jave - - + + + + + + + + + + + + + + + + + + UTF-8 1.7.25 @@ -54,7 +54,9 @@ test + + jave org.apache.maven.plugins @@ -73,4 +75,14 @@ + + + + releases + http://47.95.13.52:16500/repository/maven-releases/ + + + + + diff --git a/src/main/java/it/sauronsoftware/jave/AudioUtils.java b/src/main/java/it/sauronsoftware/jave/AudioUtils.java index 341e16a..d9d94b4 100644 --- a/src/main/java/it/sauronsoftware/jave/AudioUtils.java +++ b/src/main/java/it/sauronsoftware/jave/AudioUtils.java @@ -45,9 +45,6 @@ public static void amrToWav(File source, File target) { } public static void convert(File source, File target, String format) { - if (!source.exists()) { - throw new IllegalArgumentException("source file does not exists: " + source.getAbsoluteFile()); - } AudioAttributes audio = new AudioAttributes(); Encoder encoder = new IgnoreErrorEncoder(); audio.setCodec(LIBMP_3_LAME); diff --git a/src/main/java/it/sauronsoftware/jave/DefaultFFMPEGLocator.java b/src/main/java/it/sauronsoftware/jave/DefaultFFMPEGLocator.java index 70e38ca..a4722bc 100644 --- a/src/main/java/it/sauronsoftware/jave/DefaultFFMPEGLocator.java +++ b/src/main/java/it/sauronsoftware/jave/DefaultFFMPEGLocator.java @@ -109,7 +109,7 @@ public DefaultFFMPEGLocator() { } @Override - protected String getFFMPEGExecutablePath() { + public String getFFMPEGExecutablePath() { return path; } diff --git a/src/main/java/it/sauronsoftware/jave/Encoder.java b/src/main/java/it/sauronsoftware/jave/Encoder.java index 3e89beb..655cd30 100644 --- a/src/main/java/it/sauronsoftware/jave/Encoder.java +++ b/src/main/java/it/sauronsoftware/jave/Encoder.java @@ -22,9 +22,9 @@ import java.io.File; import java.io.IOException; import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.Hashtable; -import java.util.StringTokenizer; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -739,6 +739,9 @@ public void encode(File source, File target, EncodingAttributes attributes) public void encode(File source, File target, EncodingAttributes attributes, EncoderProgressListener listener) throws IllegalArgumentException, InputFormatException, EncoderException { + if (!source.exists()) { + throw new IllegalArgumentException("source file does not exists: " + source.getAbsoluteFile()); + } String formatAttribute = attributes.getFormat(); Float offsetAttribute = attributes.getOffset(); Float durationAttribute = attributes.getDuration(); @@ -787,8 +790,7 @@ public void encode(File source, File target, EncodingAttributes attributes, VideoSize size = videoAttributes.getSize(); if (size != null) { ffmpeg.addArgument("-s"); - ffmpeg.addArgument(String.valueOf(size.getWidth()) + "x" - + String.valueOf(size.getHeight())); + ffmpeg.addArgument(size.getWidth() + "x" + size.getHeight()); } } if (audioAttributes == null) { @@ -820,10 +822,13 @@ public void encode(File source, File target, EncodingAttributes attributes, ffmpeg.addArgument(String.valueOf(volume.intValue())); } } + ffmpeg.addArgument("-f"); ffmpeg.addArgument(formatAttribute); - ffmpeg.addArgument("-y"); - ffmpeg.addArgument(target.getAbsolutePath()); + + //根据不同的format插入不同的命令参数 + FormatEnum.get(formatAttribute).handle(ffmpeg, target); + try { ffmpeg.execute(); } catch (IOException e) { @@ -839,9 +844,7 @@ public void encode(File source, File target, EncodingAttributes attributes, } } - protected void processErrorOutput(EncodingAttributes attributes, BufferedReader errorReader, File source, EncoderProgressListener listener) throws EncoderException, IOException { - String lastWarning = null; long progress = 0L; Float offsetAttribute = attributes.getOffset(); MultimediaInfo info = parseMultimediaInfo(source, (RBufferedReader)errorReader); @@ -862,76 +865,53 @@ protected void processErrorOutput(EncodingAttributes attributes, BufferedReader } int step = 0; String line; + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss"); + Calendar calendar = Calendar.getInstance(); while ((line = errorReader.readLine()) != null) { if (step == 0) { if (line.startsWith("WARNING: ")) { - if (listener != null) - listener.message(line); + if (listener != null) listener.message(line); } else { - if (!line.startsWith("Output #0")) { - throw new EncoderException(line); - } + if (!line.startsWith("Output #0")) + if (listener != null) listener.message(line); step++; } - } else if ((step == 1) && - (!line.startsWith(" "))) { + } else if ((step == 1) && (!line.startsWith(" "))) { step++; - } - - if (step == 2) { - if (!line.startsWith("Stream mapping:")) { - throw new EncoderException(line); - } + } else if (step == 2) { + if (!line.startsWith("Stream mapping:")) + if (listener != null) listener.message(line); step++; - } - else if ((step == 3) && - (!line.startsWith(" "))) { + } else if ((step == 3) && (!line.startsWith(" "))) { step++; - } - - if (step == 4) { + } else if (step == 4) { line = line.trim(); if (line.length() > 0) { Hashtable table = parseProgressInfoLine(line); - if (table == null) { - if (listener != null) { - listener.message(line); - } - lastWarning = line; - } else { + if (table != null) { if (listener != null) { String time = (String)table.get("time"); - if (time != null) { - int dot = time.indexOf(46); - if ((dot > 0) && (dot == time.length() - 2) && (duration > 0L)) - { - String p1 = time.substring(0, dot); - String p2 = time.substring(dot + 1); - try { - long i1 = Long.parseLong(p1); - long i2 = Long.parseLong(p2); - progress = i1 * 1000L + i2 * 100L; - - int perm = (int)Math.round(progress * 1000L / duration); - - if (perm > 1000) { - perm = 1000; - } - listener.progress(perm); - } - catch (NumberFormatException e) { - } + if (time != null && (duration > 0L)) { + try { + Date data = simpleDateFormat.parse(time); + calendar.setTime(data); + int hour = calendar.get(Calendar.HOUR_OF_DAY); + int minute = calendar.get(Calendar.MINUTE); + int second = calendar.get(Calendar.SECOND); + long i1 = (second + minute * 60 + hour * 60 * 60); + progress = i1 * 1000L; + int perm = Math.round(progress * 1000L / duration); + if (perm > 1000) perm = 1000; + listener.progress(perm); + } catch (Exception e) { + e.printStackTrace(); } + } } - lastWarning = null; } } } } - if ((lastWarning != null) && - (!SUCCESS_PATTERN.matcher(lastWarning).matches())) - throw new EncoderException(lastWarning); } - } diff --git a/src/main/java/it/sauronsoftware/jave/FFMPEGExecutor.java b/src/main/java/it/sauronsoftware/jave/FFMPEGExecutor.java index 644d1bf..3162b5d 100644 --- a/src/main/java/it/sauronsoftware/jave/FFMPEGExecutor.java +++ b/src/main/java/it/sauronsoftware/jave/FFMPEGExecutor.java @@ -32,7 +32,7 @@ * * @author Carlo Pelliccia */ -class FFMPEGExecutor { +public class FFMPEGExecutor { private static final Logger log = LoggerFactory.getLogger(FFMPEGExecutor.class); /** * The path of the ffmpeg executable. diff --git a/src/main/java/it/sauronsoftware/jave/FFMPEGLocator.java b/src/main/java/it/sauronsoftware/jave/FFMPEGLocator.java index 756c3ec..4fc8c7b 100644 --- a/src/main/java/it/sauronsoftware/jave/FFMPEGLocator.java +++ b/src/main/java/it/sauronsoftware/jave/FFMPEGLocator.java @@ -33,7 +33,7 @@ public abstract class FFMPEGLocator { * * @return The path of the ffmpeg executable. */ - protected abstract String getFFMPEGExecutablePath(); + public abstract String getFFMPEGExecutablePath(); /** * It returns a brand new {@link FFMPEGExecutor}, ready to be used in a @@ -42,7 +42,7 @@ public abstract class FFMPEGLocator { * @return A newly instanced {@link FFMPEGExecutor}, using this locator to * call the ffmpeg executable. */ - FFMPEGExecutor createExecutor() { + public FFMPEGExecutor createExecutor() { return new FFMPEGExecutor(getFFMPEGExecutablePath()); } diff --git a/src/main/java/it/sauronsoftware/jave/FormatEnum.java b/src/main/java/it/sauronsoftware/jave/FormatEnum.java new file mode 100644 index 0000000..98b2339 --- /dev/null +++ b/src/main/java/it/sauronsoftware/jave/FormatEnum.java @@ -0,0 +1,52 @@ +package it.sauronsoftware.jave; + +import java.io.File; + +/** + * @description: + * @author: zhuyawei + * @date: 2020-01-08 13:39 + */ +public enum FormatEnum { + def(){ + @Override + public void handle(FFMPEGExecutor ffmpeg, File target) { + ffmpeg.addArgument("-y"); + ffmpeg.addArgument(target.getAbsolutePath()); + } + }, + ssegment(){ + @Override + public void handle(FFMPEGExecutor ffmpeg, File target) { + ffmpeg.addArgument("-map"); + ffmpeg.addArgument("0"); + ffmpeg.addArgument("-segment_format"); + ffmpeg.addArgument("mpegts"); + ffmpeg.addArgument("-segment_list"); + if(!target.getParentFile().exists())target.getParentFile().mkdirs(); + ffmpeg.addArgument(target.getAbsolutePath());//拼接存放目录 + ffmpeg.addArgument("-segment_time"); + ffmpeg.addArgument("10"); + ffmpeg.addArgument(target.getParent() + File.separator + "%03d.ts");//拼接存放目录 + } + }; + + FormatEnum() {} + + public abstract void handle(FFMPEGExecutor ffmpeg, File target); + + public static FormatEnum get(String name){ + if(name == null || name.isEmpty()) return def; + try{ + return FormatEnum.valueOf(name); + }catch (IllegalArgumentException e){ + return def; + } + } + + public static void main(String[] args) { + + System.out.println(FormatEnum.get("ssegment")); + } + +} diff --git a/src/main/java/it/sauronsoftware/jave/VideoUtils.java b/src/main/java/it/sauronsoftware/jave/VideoUtils.java index c3108bf..3fa491c 100644 --- a/src/main/java/it/sauronsoftware/jave/VideoUtils.java +++ b/src/main/java/it/sauronsoftware/jave/VideoUtils.java @@ -12,15 +12,11 @@ public class VideoUtils { /** * 获取视频缩略图 - * * @param source 视频来源 * @param imageTarget 缩略图存放目标文件 * @param offset 时间(秒) */ public static void thumbnail(File source, File imageTarget, float offset) { - if (!source.exists()) { - throw new IllegalArgumentException("source file does not exists: " + source.getAbsoluteFile()); - } Encoder encoder = new IgnoreErrorEncoder(); VideoAttributes video = new VideoAttributes(); EncodingAttributes attrs = new EncodingAttributes(); @@ -33,6 +29,50 @@ public static void thumbnail(File source, File imageTarget, float offset) { } catch (Exception e) { throw new IllegalStateException("error: ", e); } + } + + public static void mp4ToM3u8(String source, String target) { + mp4ToM3u8(source, target, null, null); + } + + public static void mp4ToM3u8(File source, File target) { + mp4ToM3u8(source, target, null, null); + } + + public static void mp4ToM3u8(String source, String target, VideoSize videoSize) { + mp4ToM3u8(source, target, videoSize, null); + } + + public static void mp4ToM3u8(File source, File target, VideoSize videoSize) { + mp4ToM3u8(source, target, videoSize, null); + } + + public static void mp4ToM3u8(String source, String target, VideoSize videoSize, EncoderProgressListener listener) { + mp4ToM3u8(new File(source), new File(target), videoSize, listener); + } + /** + * mp4转m3u8 + * @param source + */ + public static void mp4ToM3u8(File source, File target, VideoSize videoSize, EncoderProgressListener listener) { + Encoder encoder = new Encoder(); + VideoAttributes video = new VideoAttributes(); + video.setCodec("libx264"); + video.setSize(videoSize); + AudioAttributes audio = new AudioAttributes(); + audio.setCodec("mp3"); + EncodingAttributes attrs = new EncodingAttributes(); + attrs.setFormat(FormatEnum.ssegment.name()); + attrs.setVideoAttributes(video); + attrs.setAudioAttributes(audio); + try { + encoder.encode(source, target, attrs, listener); + } catch (Exception e) { + throw new IllegalStateException("error: ", e); + } } + + + } \ No newline at end of file