From 95be28e515557e7e9fe2a0b1ccb9ba873cd86eb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E4=BA=9A=E4=BC=9F?= Date: Wed, 8 Jan 2020 14:52:17 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E5=BC=80=E6=94=BEFFMPEGExecutor=E7=B1=BB?= =?UTF-8?q?=E5=92=8CFFMPEGLocator=E7=B1=BB=E7=9A=84createExecutor=E6=96=B9?= =?UTF-8?q?=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../it/sauronsoftware/jave/AudioUtils.java | 3 -- .../jave/DefaultFFMPEGLocator.java | 2 +- .../java/it/sauronsoftware/jave/Encoder.java | 34 ++++++++++-- .../sauronsoftware/jave/FFMPEGExecutor.java | 2 +- .../it/sauronsoftware/jave/FFMPEGLocator.java | 4 +- .../it/sauronsoftware/jave/FormatEnum.java | 52 +++++++++++++++++++ .../it/sauronsoftware/jave/VideoUtils.java | 37 +++++++++++-- 7 files changed, 119 insertions(+), 15 deletions(-) create mode 100644 src/main/java/it/sauronsoftware/jave/FormatEnum.java 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..094dcd2 100644 --- a/src/main/java/it/sauronsoftware/jave/Encoder.java +++ b/src/main/java/it/sauronsoftware/jave/Encoder.java @@ -24,6 +24,7 @@ import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Hashtable; +import java.util.List; import java.util.StringTokenizer; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -739,6 +740,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 +791,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 +823,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,6 +845,26 @@ public void encode(File source, File target, EncodingAttributes attributes, } } + /** + * + * @param cmdList + * @throws EncoderException + */ + public void encode(File source, List cmdList, EncoderProgressListener listener) throws EncoderException { + FFMPEGExecutor ffmpeg = locator.createExecutor(); + ffmpeg.addArgument("-i"); + ffmpeg.addArgument(source.getAbsolutePath()); + for (String s : cmdList) { + ffmpeg.addArgument(s); + } + try { + ffmpeg.execute(); + } catch (IOException e) { + throw new EncoderException(e); + } finally { + ffmpeg.destroy(); + } + } protected void processErrorOutput(EncodingAttributes attributes, BufferedReader errorReader, File source, EncoderProgressListener listener) throws EncoderException, IOException { String lastWarning = null; 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..efe6a61 100644 --- a/src/main/java/it/sauronsoftware/jave/VideoUtils.java +++ b/src/main/java/it/sauronsoftware/jave/VideoUtils.java @@ -1,6 +1,8 @@ package it.sauronsoftware.jave; import java.io.File; +import java.util.ArrayList; +import java.util.List; /** * 视频相关工具 @@ -12,15 +14,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 +31,37 @@ 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, VideoSize videoSize) { + mp4ToM3u8(new File(source), new File(target), videoSize); + } + + /** + * mp4转m3u8 + * @param source + */ + public static void mp4ToM3u8(File source, File target, VideoSize videoSize) { + Encoder encoder = new IgnoreErrorEncoder(); + 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); + } catch (Exception e) { + throw new IllegalStateException("error: ", e); + } } + + + + } \ No newline at end of file From 4fcc59867b003b244c5a99db22c64216115380bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E4=BA=9A=E4=BC=9F?= Date: Wed, 8 Jan 2020 14:54:22 +0800 Subject: [PATCH 2/4] =?UTF-8?q?VideoUtils=20=E6=96=B0=E5=A2=9Em3u8?= =?UTF-8?q?=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/it/sauronsoftware/jave/Encoder.java | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/src/main/java/it/sauronsoftware/jave/Encoder.java b/src/main/java/it/sauronsoftware/jave/Encoder.java index 094dcd2..7d8c6a6 100644 --- a/src/main/java/it/sauronsoftware/jave/Encoder.java +++ b/src/main/java/it/sauronsoftware/jave/Encoder.java @@ -845,27 +845,6 @@ public void encode(File source, File target, EncodingAttributes attributes, } } - /** - * - * @param cmdList - * @throws EncoderException - */ - public void encode(File source, List cmdList, EncoderProgressListener listener) throws EncoderException { - FFMPEGExecutor ffmpeg = locator.createExecutor(); - ffmpeg.addArgument("-i"); - ffmpeg.addArgument(source.getAbsolutePath()); - for (String s : cmdList) { - ffmpeg.addArgument(s); - } - try { - ffmpeg.execute(); - } catch (IOException e) { - throw new EncoderException(e); - } finally { - ffmpeg.destroy(); - } - } - protected void processErrorOutput(EncodingAttributes attributes, BufferedReader errorReader, File source, EncoderProgressListener listener) throws EncoderException, IOException { String lastWarning = null; long progress = 0L; From ed3f1d7dc9be020a4bf7bde8343434d2d535202d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E4=BA=9A=E4=BC=9F?= Date: Wed, 8 Jan 2020 16:38:55 +0800 Subject: [PATCH 3/4] =?UTF-8?q?m3u8=E8=BD=AC=E8=BD=AC=E6=8D=A2=E7=9B=91?= =?UTF-8?q?=E5=90=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/it/sauronsoftware/jave/Encoder.java | 85 +++++++------------ .../it/sauronsoftware/jave/VideoUtils.java | 18 +++- 2 files changed, 45 insertions(+), 58 deletions(-) diff --git a/src/main/java/it/sauronsoftware/jave/Encoder.java b/src/main/java/it/sauronsoftware/jave/Encoder.java index 7d8c6a6..655cd30 100644 --- a/src/main/java/it/sauronsoftware/jave/Encoder.java +++ b/src/main/java/it/sauronsoftware/jave/Encoder.java @@ -22,10 +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.List; -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; @@ -846,7 +845,6 @@ 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); @@ -867,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/VideoUtils.java b/src/main/java/it/sauronsoftware/jave/VideoUtils.java index efe6a61..3c18f3d 100644 --- a/src/main/java/it/sauronsoftware/jave/VideoUtils.java +++ b/src/main/java/it/sauronsoftware/jave/VideoUtils.java @@ -42,7 +42,20 @@ public static void mp4ToM3u8(String source, String target, VideoSize videoSize) * @param source */ public static void mp4ToM3u8(File source, File target, VideoSize videoSize) { - Encoder encoder = new IgnoreErrorEncoder(); + 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 IgnoreErrorEncoder(); + Encoder encoder = new Encoder(); VideoAttributes video = new VideoAttributes(); video.setCodec("libx264"); video.setSize(videoSize); @@ -55,7 +68,7 @@ public static void mp4ToM3u8(File source, File target, VideoSize videoSize) { attrs.setVideoAttributes(video); attrs.setAudioAttributes(audio); try { - encoder.encode(source, target, attrs); + encoder.encode(source, target, attrs, listener); } catch (Exception e) { throw new IllegalStateException("error: ", e); } @@ -63,5 +76,4 @@ public static void mp4ToM3u8(File source, File target, VideoSize videoSize) { - } \ No newline at end of file From 1a0ffeb44dec7af5640bbf700127eef36b3ef4ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E4=BA=9A=E4=BC=9F?= Date: Sun, 19 Jan 2020 10:04:01 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E8=87=B3maven=E7=A7=81?= =?UTF-8?q?=E6=9C=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 52 ++++++++++++------- .../it/sauronsoftware/jave/VideoUtils.java | 19 ++++--- 2 files changed, 41 insertions(+), 30 deletions(-) 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/VideoUtils.java b/src/main/java/it/sauronsoftware/jave/VideoUtils.java index 3c18f3d..3fa491c 100644 --- a/src/main/java/it/sauronsoftware/jave/VideoUtils.java +++ b/src/main/java/it/sauronsoftware/jave/VideoUtils.java @@ -1,8 +1,6 @@ package it.sauronsoftware.jave; import java.io.File; -import java.util.ArrayList; -import java.util.List; /** * 视频相关工具 @@ -33,14 +31,18 @@ public static void thumbnail(File source, File imageTarget, float offset) { } } + 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(new File(source), new File(target), videoSize); + mp4ToM3u8(source, target, videoSize, null); } - /** - * mp4转m3u8 - * @param source - */ public static void mp4ToM3u8(File source, File target, VideoSize videoSize) { mp4ToM3u8(source, target, videoSize, null); } @@ -54,15 +56,12 @@ public static void mp4ToM3u8(String source, String target, VideoSize videoSize, * @param source */ public static void mp4ToM3u8(File source, File target, VideoSize videoSize, EncoderProgressListener listener) { -// Encoder encoder = new IgnoreErrorEncoder(); 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);