diff --git a/src/zutil/net/http/servlet/HttpServletRequestImpl.java b/src/zutil/net/http/servlet/HttpServletRequestImpl.java new file mode 100644 index 0000000..aab5b3c --- /dev/null +++ b/src/zutil/net/http/servlet/HttpServletRequestImpl.java @@ -0,0 +1,386 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Ziver Koc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package zutil.net.http.servlet; + +import javax.servlet.*; +import javax.servlet.http.*; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.security.Principal; +import java.util.Collection; +import java.util.Enumeration; +import java.util.Locale; +import java.util.Map; + + +public class HttpServletRequestImpl implements HttpServletRequest { + + + @Override + public String getAuthType() { + return null; + } + + @Override + public Cookie[] getCookies() { + return new Cookie[0]; + } + + @Override + public long getDateHeader(String s) { + return 0; + } + + @Override + public String getHeader(String s) { + return null; + } + + @Override + public Enumeration getHeaders(String s) { + return null; + } + + @Override + public Enumeration getHeaderNames() { + return null; + } + + @Override + public int getIntHeader(String s) { + return 0; + } + + @Override + public String getMethod() { + return null; + } + + @Override + public String getPathInfo() { + return null; + } + + @Override + public String getPathTranslated() { + return null; + } + + @Override + public String getContextPath() { + return null; + } + + @Override + public String getQueryString() { + return null; + } + + @Override + public String getRemoteUser() { + return null; + } + + @Override + public boolean isUserInRole(String s) { + return false; + } + + @Override + public Principal getUserPrincipal() { + return null; + } + + @Override + public String getRequestedSessionId() { + return null; + } + + @Override + public String getRequestURI() { + return null; + } + + @Override + public StringBuffer getRequestURL() { + return null; + } + + @Override + public String getServletPath() { + return null; + } + + @Override + public HttpSession getSession(boolean b) { + return null; + } + + @Override + public HttpSession getSession() { + return null; + } + + @Override + public String changeSessionId() { + return null; + } + + @Override + public boolean isRequestedSessionIdValid() { + return false; + } + + @Override + public boolean isRequestedSessionIdFromCookie() { + return false; + } + + @Override + public boolean isRequestedSessionIdFromURL() { + return false; + } + + @Override + public boolean isRequestedSessionIdFromUrl() { + return false; + } + + @Override + public boolean authenticate(HttpServletResponse httpServletResponse) throws IOException, ServletException { + return false; + } + + @Override + public void login(String s, String s1) throws ServletException { + + } + + @Override + public void logout() throws ServletException { + + } + + @Override + public Collection getParts() throws IOException, ServletException { + return null; + } + + @Override + public Part getPart(String s) throws IOException, ServletException { + return null; + } + + @Override + public T upgrade(Class aClass) throws IOException, ServletException { + return null; + } + + @Override + public Object getAttribute(String s) { + return null; + } + + @Override + public Enumeration getAttributeNames() { + return null; + } + + @Override + public String getCharacterEncoding() { + return null; + } + + @Override + public void setCharacterEncoding(String s) throws UnsupportedEncodingException { + + } + + @Override + public int getContentLength() { + return 0; + } + + @Override + public long getContentLengthLong() { + return 0; + } + + @Override + public String getContentType() { + return null; + } + + @Override + public ServletInputStream getInputStream() throws IOException { + return null; + } + + @Override + public String getParameter(String s) { + return null; + } + + @Override + public Enumeration getParameterNames() { + return null; + } + + @Override + public String[] getParameterValues(String s) { + return new String[0]; + } + + @Override + public Map getParameterMap() { + return null; + } + + @Override + public String getProtocol() { + return null; + } + + @Override + public String getScheme() { + return null; + } + + @Override + public String getServerName() { + return null; + } + + @Override + public int getServerPort() { + return 0; + } + + @Override + public BufferedReader getReader() throws IOException { + return null; + } + + @Override + public String getRemoteAddr() { + return null; + } + + @Override + public String getRemoteHost() { + return null; + } + + @Override + public void setAttribute(String s, Object o) { + + } + + @Override + public void removeAttribute(String s) { + + } + + @Override + public Locale getLocale() { + return null; + } + + @Override + public Enumeration getLocales() { + return null; + } + + @Override + public boolean isSecure() { + return false; + } + + @Override + public RequestDispatcher getRequestDispatcher(String s) { + return null; + } + + @Override + public String getRealPath(String s) { + return null; + } + + @Override + public int getRemotePort() { + return 0; + } + + @Override + public String getLocalName() { + return null; + } + + @Override + public String getLocalAddr() { + return null; + } + + @Override + public int getLocalPort() { + return 0; + } + + @Override + public ServletContext getServletContext() { + return null; + } + + @Override + public AsyncContext startAsync() throws IllegalStateException { + return null; + } + + @Override + public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) throws IllegalStateException { + return null; + } + + @Override + public boolean isAsyncStarted() { + return false; + } + + @Override + public boolean isAsyncSupported() { + return false; + } + + @Override + public AsyncContext getAsyncContext() { + return null; + } + + @Override + public DispatcherType getDispatcherType() { + return null; + } +} diff --git a/src/zutil/net/http/servlet/HttpServletResponseImpl.java b/src/zutil/net/http/servlet/HttpServletResponseImpl.java new file mode 100644 index 0000000..f8077cc --- /dev/null +++ b/src/zutil/net/http/servlet/HttpServletResponseImpl.java @@ -0,0 +1,222 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Ziver Koc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package zutil.net.http.servlet; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Collection; +import java.util.Locale; + +public class HttpServletResponseImpl implements HttpServletResponse { + + + @Override + public void addCookie(Cookie cookie) { + + } + + @Override + public boolean containsHeader(String s) { + return false; + } + + @Override + public String encodeURL(String s) { + return null; + } + + @Override + public String encodeRedirectURL(String s) { + return null; + } + + @Override + public String encodeUrl(String s) { + return null; + } + + @Override + public String encodeRedirectUrl(String s) { + return null; + } + + @Override + public void sendError(int i, String s) throws IOException { + + } + + @Override + public void sendError(int i) throws IOException { + + } + + @Override + public void sendRedirect(String s) throws IOException { + + } + + @Override + public void setDateHeader(String s, long l) { + + } + + @Override + public void addDateHeader(String s, long l) { + + } + + @Override + public void setHeader(String s, String s1) { + + } + + @Override + public void addHeader(String s, String s1) { + + } + + @Override + public void setIntHeader(String s, int i) { + + } + + @Override + public void addIntHeader(String s, int i) { + + } + + @Override + public void setStatus(int i) { + + } + + @Override + public void setStatus(int i, String s) { + + } + + @Override + public int getStatus() { + return 0; + } + + @Override + public String getHeader(String s) { + return null; + } + + @Override + public Collection getHeaders(String s) { + return null; + } + + @Override + public Collection getHeaderNames() { + return null; + } + + @Override + public String getCharacterEncoding() { + return null; + } + + @Override + public String getContentType() { + return null; + } + + @Override + public ServletOutputStream getOutputStream() throws IOException { + return null; + } + + @Override + public PrintWriter getWriter() throws IOException { + return null; + } + + @Override + public void setCharacterEncoding(String s) { + + } + + @Override + public void setContentLength(int i) { + + } + + @Override + public void setContentLengthLong(long l) { + + } + + @Override + public void setContentType(String s) { + + } + + @Override + public void setBufferSize(int i) { + + } + + @Override + public int getBufferSize() { + return 0; + } + + @Override + public void flushBuffer() throws IOException { + + } + + @Override + public void resetBuffer() { + + } + + @Override + public boolean isCommitted() { + return false; + } + + @Override + public void reset() { + + } + + @Override + public void setLocale(Locale locale) { + + } + + @Override + public Locale getLocale() { + return null; + } +} diff --git a/src/zutil/net/http/servlet/HttpSessionImpl.java b/src/zutil/net/http/servlet/HttpSessionImpl.java new file mode 100644 index 0000000..5223eeb --- /dev/null +++ b/src/zutil/net/http/servlet/HttpSessionImpl.java @@ -0,0 +1,119 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Ziver Koc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package zutil.net.http.servlet; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpSession; +import javax.servlet.http.HttpSessionContext; +import java.util.Enumeration; + + +public class HttpSessionImpl implements HttpSession { + + @Override + public long getCreationTime() { + return 0; + } + + @Override + public String getId() { + return null; + } + + @Override + public long getLastAccessedTime() { + return 0; + } + + @Override + public ServletContext getServletContext() { + return null; + } + + @Override + public void setMaxInactiveInterval(int interval) { + + } + + @Override + public int getMaxInactiveInterval() { + return 0; + } + + @Override + public HttpSessionContext getSessionContext() { + throw new UnsupportedOperationException(); + } + + @Override + public Object getAttribute(String name) { + return null; + } + + @Override + public Object getValue(String name) { + return null; + } + + @Override + public Enumeration getAttributeNames() { + return null; + } + + @Override + public String[] getValueNames() { + return new String[0]; + } + + @Override + public void setAttribute(String name, Object value) { + + } + + @Override + public void putValue(String name, Object value) { + + } + + @Override + public void removeAttribute(String name) { + + } + + @Override + public void removeValue(String name) { + + } + + @Override + public void invalidate() { + + } + + @Override + public boolean isNew() { + return false; + } +} diff --git a/src/zutil/osal/app/ffmpeg/FFmpeg.java b/src/zutil/osal/app/ffmpeg/FFmpeg.java new file mode 100644 index 0000000..0b01603 --- /dev/null +++ b/src/zutil/osal/app/ffmpeg/FFmpeg.java @@ -0,0 +1,99 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021 Ziver Koc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package zutil.osal.app.ffmpeg; + +import zutil.osal.app.ffmpeg.FFmpegConstants.*; + +import java.util.ArrayList; +import java.util.List; + +/** + * Class for building a ffmpeg commandline for execution + * + * @see FFmpeg Commandline Documentation + */ +public class FFmpeg { + + private FFmpegLogLevel logLevel; + private boolean overwriteOutput = false; + private List inputs = new ArrayList<>(); + private List outputs = new ArrayList<>(); + + + public FFmpeg() {} + + + public void setLogLevel(FFmpegLogLevel level) { + this.logLevel = level; + } + + /** + * @param overwrite Set to true if all outputs should be overwritten if they exist, false if FFmpeg should exit with error. + */ + public void enableOutputOverwrite(boolean overwrite) { + this.overwriteOutput = overwrite; + } + + public void addInput(FFmpegInput input) { + inputs.add(input); + } + + public void addOutput(FFmpegOutput output) { + outputs.add(output); + } + + + public String buildCommand() { + StringBuilder command = new StringBuilder(); + command.append("ffmpeg"); + + // General inputs + + if (logLevel != null) { + command.append(" -loglevel ").append(logLevel.toString().toLowerCase()); + } + + if (overwriteOutput) { + command.append(" -y"); + } + + // TODO: -progress url (global) for progress status + // TODO: -stdin Enable interaction on standard input + + // Inputs + + for (FFmpegInput input : inputs) { + command.append(" ").append(input.buildCommand()); + } + + // Outputs + + for (FFmpegOutput output : outputs) { + command.append(" ").append(output.buildCommand()); + } + + return command.toString(); + } +} diff --git a/src/zutil/osal/app/ffmpeg/FFmpegConstants.java b/src/zutil/osal/app/ffmpeg/FFmpegConstants.java new file mode 100644 index 0000000..76b5d86 --- /dev/null +++ b/src/zutil/osal/app/ffmpeg/FFmpegConstants.java @@ -0,0 +1,418 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021 Ziver Koc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package zutil.osal.app.ffmpeg; + +public final class FFmpegConstants { + + public enum FFmpegLogLevel { + /** Show nothing at all; be silent. **/ + QUIET, + /** Only show fatal errors which could lead the process to crash, such as an assertion failure. This is not currently used for anything. **/ + PANIC, + /** Only show fatal errors. These are errors after which the process absolutely cannot continue.**/ + FATAL, + /** Show all errors, including ones which can be recovered from. **/ + ERROR, + /** Show all warnings and errors. Any message related to possibly incorrect or unexpected events will be shown. **/ + WARNING, + /** Show informative messages during processing. This is in addition to warnings and errors. This is the default value. **/ + INFO, + /** Same as info, except more verbose. **/ + VERBOSE, + /** Show everything, including debugging information. **/ + DEBUG, + TRACE + } + + public enum FFmpegHwDevice { + cuda, + dxva2, + vaapi, + vdpau, + qsv, + opencl, + vulkan + } + + public enum FFmpegVideoCodec { + /** Multicolor charset for Commodore 64 (encoders: a64multi ) **/ + a64multi, + /** Multicolor charset for Commodore 64, extended with 5th color (colram) (encoders: a64multi5 )**/ + a64multi5, + /** Alias/Wavefront PIX image **/ + alias_pix, + /** AMV Video **/ + amv, + /** APNG (Animated Portable Network Graphics) image **/ + apng, + /** ASUS V1 **/ + asv1, + /** ASUS V2 **/ + asv2, + /** Alliance for Open Media AV1 (decoders: libdav1d libaom-av1 ) (encoders: libaom-av1 librav1e ) **/ + libaom_av1, + librav1e, + /** Avid 1:1 10-bit RGB Packer **/ + avrp, + /** AVS2-P2/IEEE1857.4 (decoders: libdavs2 ) (encoders: libxavs2 ) **/ + libxavs2, + /** Avid Meridien Uncompressed **/ + avui, + /** Uncompressed packed MS 4:4:4:4 **/ + ayuv, + /** BMP (Windows and OS/2 bitmap) **/ + bmp, + /** Cinepak **/ + cinepak, + /** Cirrus Logic AccuPak **/ + cljr, + /** Copy input to output without modification **/ + copy, + /** Dirac (encoders: vc2 ) **/ + vc2, + /** VC3/DNxHD **/ + dnxhd, + /** DPX (Digital Picture Exchange) image **/ + dpx, + /** DV (Digital Video) **/ + dvvideo, + /** FFmpeg video codec #1 **/ + ffv1, + /** Huffyuv FFmpeg variant **/ + ffvhuff, + /** FITS (Flexible Image Transport System) **/ + fits, + /** Flash Screen Video v1 **/ + flashsv, + /** Flash Screen Video v2 **/ + flashsv2, + /** FLV / Sorenson Spark / Sorenson H.263 (Flash Video) (decoders: flv ) (encoders: flv ) **/ + flv, + /** CompuServe GIF (Graphics Interchange Format) **/ + gif, + /** H.261 **/ + h261, + /** H.263 / H.263-1996, H.263+ / H.263-1998 / H.263 version 2 **/ + h263, + /** H.263+ / H.263-1998 / H.263 version 2 **/ + h263p, + /** H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (decoders: h264 h264_qsv h264_cuvid ) (encoders: libx264 libx264rgb h264_amf h264_mf h264_nvenc h264_qsv nvenc nvenc_h264 ) **/ + libx264, + libx264rgb, + h264_amf, + h264_mf, + h264_nvenc, + h264_qsv, + nvenc, + nvenc_h264, + /** H.265 / HEVC (High Efficiency Video Coding) (decoders: hevc hevc_qsv hevc_cuvid ) (encoders: libx265 nvenc_hevc hevc_amf hevc_mf hevc_nvenc hevc_qsv ) **/ + libx265, + nvenc_hevc, + hevc_amf, + hevc_mf, + hevc_nvenc, + hevc_qsv, + /** HuffYUV **/ + huffyuv, + /** JPEG 2000 (decoders: jpeg2000 libopenjpeg ) (encoders: jpeg2000 libopenjpeg ) **/ + jpeg2000, + libopenjpeg, + /** JPEG-LS **/ + jpegls, + /** Lossless JPEG **/ + ljpeg, + /** MagicYUV video **/ + magicyuv, + /** Motion JPEG (decoders: mjpeg mjpeg_cuvid mjpeg_qsv ) (encoders: mjpeg mjpeg_qsv ) **/ + mjpeg, + mjpeg_qsv, + /** MPEG-1 video (decoders: mpeg1video mpeg1_cuvid ) **/ + mpeg1video, + /** MPEG-2 video (decoders: mpeg2video mpegvideo mpeg2_qsv mpeg2_cuvid ) (encoders: mpeg2video mpeg2_qsv ) **/ + mpeg2video, + mpeg2_qsv, + /** MPEG-4 part 2 (decoders: mpeg4 mpeg4_cuvid ) (encoders: mpeg4 libxvid ) **/ + mpeg4, + libxvid, + /** MPEG-4 part 2 Microsoft variant version 2 **/ + msmpeg4v2, + /** MPEG-4 part 2 Microsoft variant version 3 (decoders: msmpeg4 ) (encoders: msmpeg4 ) **/ + msmpeg4, + /** Microsoft Video 1 **/ + msvideo1, + /** PAM (Portable AnyMap) image **/ + pam, + /** PBM (Portable BitMap) image **/ + pbm, + /** PC Paintbrush PCX image **/ + pcx, + /** PGM (Portable GrayMap) image **/ + pgm, + /** PGMYUV (Portable GrayMap YUV) image **/ + pgmyuv, + /** PNG (Portable Network Graphics) image **/ + png, + /** PPM (Portable PixelMap) image **/ + ppm, + /** Apple ProRes (iCodec Pro) (encoders: prores prores_aw prores_ks ) **/ + prores, + prores_aw, + prores_ks, + /** QuickTime Animation (RLE) video **/ + qtrle, + /** AJA Kona 10-bit RGB Codec **/ + r10k, + /** Uncompressed RGB 10-bit **/ + r210, + /** raw video **/ + rawvideo, + /** id RoQ video (decoders: roqvideo ) (encoders: roqvideo ) **/ + roqvideo, + /** RealVideo 1.0 **/ + rv10, + /** RealVideo 2.0 **/ + rv20, + /** SGI image **/ + sgi, + /** Snow **/ + snow, + /** Sun Rasterfile image **/ + sunrast, + /** Sorenson Vector Quantizer 1 / Sorenson Video 1 / SVQ1 **/ + svq1, + /** Truevision Targa image **/ + targa, + /** Theora (encoders: libtheora ) **/ + libtheora, + /** TIFF image **/ + tiff, + /** Ut Video **/ + utvideo, + /** Uncompressed 4:2:2 10-bit **/ + v210, + /** Uncompressed packed 4:4:4 **/ + v308, + /** Uncompressed packed QT 4:4:4:4 **/ + v408, + /** Uncompressed 4:4:4 10-bit **/ + v410, + /** On2 VP8 (decoders: vp8 libvpx vp8_cuvid vp8_qsv ) (encoders: libvpx ) **/ + libvpx, + /** Google VP9 (decoders: vp9 libvpx-vp9 vp9_cuvid vp9_qsv ) (encoders: libvpx-vp9 vp9_qsv ) **/ + libvpx_vp9, + vp9_qsv, + /** WebP (encoders: libwebp_anim libwebp ) **/ + libwebp_anim, + libwebp, + /** Windows Media Video 7 **/ + wmv1, + /** Windows Media Video 8 **/ + wmv2, + /** AVFrame to AVPacket passthrough **/ + wrapped_avframe, + /** XBM (X BitMap) image **/ + xbm, + /** X-face image **/ + xface, + /** XWD (X Window Dump) image **/ + xwd, + /** Uncompressed YUV 4:1:1 12-bit **/ + y41p, + /** Uncompressed packed 4:2:0 **/ + yuv4, + /** LCL (LossLess Codec Library) ZLIB **/ + zlib, + /** Zip Motion Blocks Video **/ + zmbv + } + + public enum FFmpegAudioCodec { + /** AAC (Advanced Audio Coding) (decoders: aac aac_fixed ) (encoders: aac aac_mf ) **/ + aac, + aac_mf, + /** ATSC A/52A (AC-3) (decoders: ac3 ac3_fixed ) (encoders: ac3 ac3_fixed ac3_mf ) **/ + ac3, + ac3_fixed, + ac3_mf, + /** SEGA CRI ADX ADPCM **/ + adpcm_adx, + /** G.722 ADPCM (decoders: g722 ) (encoders: g722 ) **/ + g722, + /** G.726 ADPCM (decoders: g726 ) (encoders: g726 ) **/ + g726, + /** G.726 ADPCM little-endian (decoders: g726le ) (encoders: g726le ) **/ + g726le, + /** ADPCM IMA QuickTime **/ + adpcm_ima_qt, + /** ADPCM IMA Simon & Schuster Interactive **/ + adpcm_ima_ssi, + /** ADPCM IMA WAV **/ + adpcm_ima_wav, + /** ADPCM Microsoft **/ + adpcm_ms, + /** ADPCM Shockwave Flash **/ + adpcm_swf, + /** ADPCM Yamaha **/ + adpcm_yamaha, + /** ALAC (Apple Lossless Audio Codec) **/ + alac, + /** AMR-NB (Adaptive Multi-Rate NarrowBand) (decoders: amrnb libopencore_amrnb ) (encoders: libopencore_amrnb ) **/ + libopencore_amrnb, + /** aptX (Audio Processing Technology for Bluetooth) **/ + aptx, + /** aptX HD (Audio Processing Technology for Bluetooth) **/ + aptx_hd, + /** Copy input to output without modification **/ + copy, + /** RFC 3389 Comfort Noise **/ + comfortnoise, + /** DCA (DTS Coherent Acoustics) (decoders: dca ) (encoders: dca ) **/ + dca, + /** ATSC A/52B (AC-3, E-AC-3) **/ + eac3, + /** FLAC (Free Lossless Audio Codec) **/ + flac, + /** G.723.1 **/ + g723_1, + /** MLP (Meridian Lossless Packing) **/ + mlp, + /** MP2 (MPEG audio layer 2) (decoders: mp2 mp2float ) (encoders: mp2 mp2fixed libtwolame ) **/ + mp2, + /** MP3 (MPEG audio layer 3) (decoders: mp3float mp3 ) (encoders: libmp3lame mp3_mf ) **/ + libmp3lame, + mp3_mf, + /** Nellymoser Asao **/ + nellymoser, + /** Opus (Opus Interactive Audio Codec) (decoders: opus libopus ) (encoders: opus libopus ) **/ + opus, + libopus, + /** PCM A-law / G.711 A-law **/ + pcm_alaw, + /** PCM signed 20|24-bit big-endian **/ + pcm_dvd, + /** PCM 32-bit floating point big-endian **/ + pcm_f32be, + /** PCM 32-bit floating point little-endian **/ + pcm_f32le, + /** PCM 64-bit floating point big-endian **/ + pcm_f64be, + /** PCM 64-bit floating point little-endian **/ + pcm_f64le, + /** PCM mu-law / G.711 mu-law **/ + pcm_mulaw, + /** PCM signed 16-bit big-endian **/ + pcm_s16be, + /** PCM signed 16-bit big-endian planar **/ + pcm_s16be_planar, + /** PCM signed 16-bit little-endian **/ + pcm_s16le, + /** PCM signed 16-bit little-endian planar **/ + pcm_s16le_planar, + /** PCM signed 24-bit big-endian **/ + pcm_s24be, + /** PCM D-Cinema audio signed 24-bit **/ + pcm_s24daud, + /** PCM signed 24-bit little-endian **/ + pcm_s24le, + /** PCM signed 24-bit little-endian planar **/ + pcm_s24le_planar, + /** PCM signed 32-bit big-endian **/ + pcm_s32be, + /** PCM signed 32-bit little-endian **/ + pcm_s32le, + /** PCM signed 32-bit little-endian planar **/ + pcm_s32le_planar, + /** PCM signed 64-bit big-endian **/ + pcm_s64be, + /** PCM signed 64-bit little-endian **/ + pcm_s64le, + /** PCM signed 8-bit **/ + pcm_s8, + /** PCM signed 8-bit planar **/ + pcm_s8_planar, + /** PCM unsigned 16-bit big-endian **/ + pcm_u16be, + /** PCM unsigned 16-bit little-endian **/ + pcm_u16le, + /** PCM unsigned 24-bit big-endian **/ + pcm_u24be, + /** PCM unsigned 24-bit little-endian **/ + pcm_u24le, + /** PCM unsigned 32-bit big-endian **/ + pcm_u32be, + /** PCM unsigned 32-bit little-endian **/ + pcm_u32le, + /** PCM unsigned 8-bit **/ + pcm_u8, + /** PCM Archimedes VIDC **/ + pcm_vidc, + /** RealAudio 1.0 (14.4K) (decoders: real_144 ) (encoders: real_144 ) **/ + real_144, + /** DPCM id RoQ **/ + roq_dpcm, + /** SMPTE 302M **/ + s302m, + /** SBC (low-complexity subband codec) **/ + sbc, + /** Sonic **/ + sonic, + /** Sonic lossless **/ + sonicls, + /** TrueHD **/ + truehd, + /** TTA (True Audio) **/ + tta, + /** Vorbis (decoders: vorbis libvorbis ) (encoders: vorbis libvorbis ) **/ + vorbis, + libvorbis, + /** WavPack **/ + wavpack, + /** Windows Media Audio 1 **/ + wmav1, + /** Windows Media Audio 2 **/ + wmav2 + } + + public enum FFmpegSubtitleCodec { + /** ASS (Advanced SSA) subtitle (decoders: ssa ass ) (encoders: ssa ass) **/ + ass, + ssa, + /** DVB subtitles (decoders: dvbsub ) (encoders: dvbsub ) **/ + dvbsub, + /** DVD subtitles (decoders: dvdsub ) (encoders: dvdsub ) **/ + dvdsub, + /** MOV text **/ + mov_text, + /** SubRip subtitle (decoders: srt subrip ) (encoders: srt subrip ) **/ + srt, + subrip, + /** raw UTF-8 text **/ + text, + /** WebVTT subtitle **/ + webvtt, + /** XSUB **/ + xsub + } +} diff --git a/src/zutil/osal/app/ffmpeg/FFmpegInput.java b/src/zutil/osal/app/ffmpeg/FFmpegInput.java new file mode 100644 index 0000000..873851c --- /dev/null +++ b/src/zutil/osal/app/ffmpeg/FFmpegInput.java @@ -0,0 +1,141 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021 Ziver Koc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package zutil.osal.app.ffmpeg; + +/** + * Class includes data related to a single input into FFmpeg + */ +public class FFmpegInput { + // General Options + + private String input; + private Float duration; + private Float positionStart; + private Float positionEnd; + + // Audio Options + + private boolean audioEnabled = true; + + // Subtitle Options + + private boolean subtitleEnabled = true; + + + + public FFmpegInput(String input) { + this.input = input; + } + + + /** + * Limit the duration of data read from the input file. + * {@link #setDuration(float)} and {@link #setEndPosition(float)} are mutually exclusive and {@link #setDuration(float)} has priority. + * + * @param duration duration in seconds + */ + public void setDuration(float duration) { + this.duration = duration; + } + /** + * Seeks in this input file to position. + * + * @param position Position in seconds + */ + public void setStartPosition(float position) { + this.positionStart = position; + } + /** + * Stop reading the input file at position. + * {@link #setDuration(float)} and {@link #setEndPosition(float)} are mutually exclusive and {@link #setDuration(float)} has priority. + * + * @param position Position in seconds + */ + public void setEndPosition(float position) { + this.positionEnd = position; + } + + // ---------------------------------------------------- + // Audio Options + // ---------------------------------------------------- + + /** + * Enable or Blocks audio from input file. (enabled by default) + * + * @param enabled Set to false to disable audio + */ + public void setAudioEnabled(boolean enabled) { + this.audioEnabled = enabled; + } + + // ---------------------------------------------------- + // Subtitle Options + // ---------------------------------------------------- + + /** + * Enable or Blocks subtitles from input file. (enabled by default) + * + * @param enabled Set to false to disable subtitles + */ + public void setSubtitleEnabled(boolean enabled) { + this.subtitleEnabled = enabled; + } + + // ---------------------------------------------------- + // Command Generation + // ---------------------------------------------------- + + protected String buildCommand() { + StringBuilder command = new StringBuilder(); + + // ---------------------------------------------------- + // General Options + // ---------------------------------------------------- + + if (positionStart != null) + command.append(" -ss ").append(positionStart); + if (positionEnd != null) + command.append(" -to ").append(positionEnd); + if (duration != null) + command.append(" -t ").append(duration); + + // ---------------------------------------------------- + // Audio Options + // ---------------------------------------------------- + + if (!audioEnabled) + command.append(" -an"); + + // ---------------------------------------------------- + // Subtitle Options + // ---------------------------------------------------- + + if (!subtitleEnabled) + command.append(" -sn"); + + command.append(" -i ").append(input); + return command.toString().trim(); + } +} \ No newline at end of file diff --git a/src/zutil/osal/app/ffmpeg/FFmpegOutput.java b/src/zutil/osal/app/ffmpeg/FFmpegOutput.java new file mode 100644 index 0000000..c985a2d --- /dev/null +++ b/src/zutil/osal/app/ffmpeg/FFmpegOutput.java @@ -0,0 +1,342 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021 Ziver Koc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package zutil.osal.app.ffmpeg; + +import zutil.osal.app.ffmpeg.FFmpegConstants.FFmpegAudioCodec; +import zutil.osal.app.ffmpeg.FFmpegConstants.FFmpegSubtitleCodec; +import zutil.osal.app.ffmpeg.FFmpegConstants.FFmpegVideoCodec; + +/** + * Class includes data related to a single output from FFmpeg + */ +public class FFmpegOutput { + // General Options + + private String output; + private Float duration; + private Float positionStart; + private Float positionEnd; + private Long fileSize; + private Integer encodingPass; + + // Video Options + + private String videoCodec; + private Float videoFrameRate; + private Integer videoWidth; + private Integer videoHeight; + private Integer videoBitRate; + private Integer videoQuality; + + // Audio Options + + private String audioCodec; + private Integer audioSampleRate; + private Integer audioChannels; + private Integer audioBitRate; + private Integer audioQuality; + private boolean audioEnabled = true; + + // Subtitle Options + + private String subtitleCodec; + private boolean subtitleEnabled = true; + + + public FFmpegOutput(String output) { + this.output = output; + } + + + /** + * Stop writing the output after its duration reaches duration. + * {@link #setDuration(float)} and {@link #setEndPosition(float)} are mutually exclusive and {@link #setDuration(float)} has priority. + * + * @param duration duration in seconds + */ + public void setDuration(float duration) { + this.duration = duration; + } + /** + * Decodes but discards input until the timestamps reach position. + * + * @param position Position in seconds + */ + public void setStartPosition(float position) { + this.positionStart = position; + } + /** + * Stop writing the output at position. + * {@link #setDuration(float)} and {@link #setEndPosition(float)} are mutually exclusive and {@link #setDuration(float)} has priority. + * + * @param position Position in seconds + */ + public void setEndPosition(float position) { + this.positionEnd = position; + } + + /** + * Set the file size limit. + * + * @param size Size of the file in bytes + */ + public void setTargetFileSize(long size) { + this.fileSize = size; + } + + /** + * Select the pass number (1 or 2). It is used to do two-pass video encoding. + * + * @param pass THe pass number + */ + public void setEncodingPass(int pass) { + this.encodingPass = pass; + } + + // ---------------------------------------------------- + // Video Options + // ---------------------------------------------------- + + /** + * Select an encoder. + * + * @param codec Codec name supported by FFmpeg + */ + public void setVideoCodec(FFmpegVideoCodec codec) { + this.videoCodec = codec.toString(); + } + /** + * Select an encoder. + * + * @param codec Codec name supported by FFmpeg + */ + public void setVideoCodec(String codec) { + this.videoCodec = codec; + } + + /** + * Duplicate or drop input frames to achieve provided constant output frame rate (fps). + * + * @param frameRate Frame rate in Hz + */ + public void setVideoFrameRate(float frameRate) { + this.videoFrameRate = frameRate; + } + + /** + * Set the target resolution of the output file. + * + * @param width The width in pixels + * @param height The height in pixels + */ + public void setVideoResolution(int width, int height) { + this.videoWidth = width; + this.videoHeight = height; + } + + /** + * Set constant video bitrate. + * + * @param bitrate Rate in number of bits + */ + public void setVideoBitRate(int bitrate) { + this.videoBitRate = bitrate; + } + + /** + * Use fixed quality scale (VBR). + * + * @param vbr The meaning of q/qscale is codec-dependent. + */ + public void setVideoQuality(int vbr) { + this.videoQuality = vbr; + } + + // ---------------------------------------------------- + // Audio Options + // ---------------------------------------------------- + + /** + * Select an encoder. + * + * @param codec Codec name supported by FFmpeg + */ + public void setAudioCodec(FFmpegAudioCodec codec) { + this.audioCodec = codec.toString(); + } + /** + * Select an encoder. + * + * @param codec Codec name supported by FFmpeg + */ + public void setAudioCodec(String codec) { + this.audioCodec = codec; + } + + /** + * Set the audio sampling frequency. For output streams it is set by default to the frequency of the corresponding input stream. + * + * @param sampleRate Audio sampling frequency + */ + public void setAudioSampleRate(int sampleRate) { + this.audioSampleRate = sampleRate; + } + + /** + * Set the number of audio channels. For output streams it is set by default to the number of input audio channels. + * + * @param channels Number of audio channels in output file + */ + public void setAudioChannels(int channels) { + this.audioChannels = channels; + } + + /** + * Set constant audio bitrate + * + * @param bitrate Rate in number of bits + */ + public void setAudioBitRate(int bitrate) { + this.audioBitRate = bitrate; + } + + /** + * Use fixed quality scale (VBR). + * + * @param vbr The meaning of q/qscale is codec-dependent. + */ + public void setAudioQuality(int vbr) { + this.audioQuality = vbr; + } + + /** + * Enable or Disables audio recording in output file. (enabled by default) + * + * @param enabled Set to false to disable audio + */ + public void setAudioEnabled(boolean enabled) { + this.audioEnabled = enabled; + } + + // ---------------------------------------------------- + // Subtitle Options + // ---------------------------------------------------- + + /** + * Select an encoder. + * + * @param codec Codec name supported by FFmpeg + */ + public void setSubtitleCodec(FFmpegSubtitleCodec codec) { + this.subtitleCodec = codec.toString(); + } + /** + * Select an encoder. + * + * @param codec Codec name supported by FFmpeg + */ + public void setSubtitleCodec(String codec) { + this.subtitleCodec = codec; + } + + /** + * Enable or Disables subtitles in output file. (enabled by default) + * + * @param enabled Set to false to disable subtitles + */ + public void setSubtitleEnabled(boolean enabled) { + this.subtitleEnabled = enabled; + } + + // ---------------------------------------------------- + // Command Generation + // ---------------------------------------------------- + + protected String buildCommand() { + StringBuilder command = new StringBuilder(); + + // ---------------------------------------------------- + // General Options + // ---------------------------------------------------- + + if (positionStart != null) + command.append(" -ss ").append(positionStart); + if (positionEnd != null) + command.append(" -to ").append(positionEnd); + if (duration != null) + command.append(" -t ").append(duration); + if (fileSize != null) + command.append(" -fs ").append(fileSize); + + if (encodingPass != null) + command.append(" -pass ").append(encodingPass); + + // ---------------------------------------------------- + // Video Options + // ---------------------------------------------------- + + if (videoCodec != null) + command.append(" -codec:v ").append(videoCodec); + if (videoFrameRate != null) + command.append(" -frames ").append(videoFrameRate); + if (videoWidth != null && videoHeight != null) + command.append(" -filter:v scale=").append(videoWidth).append(':').append(videoHeight); + if (videoBitRate != null) + command.append(" -b:v ").append(videoBitRate); + if (videoQuality != null) + command.append(" -qscale:v ").append(videoQuality); + + // ---------------------------------------------------- + // Audio Options + // ---------------------------------------------------- + + if (audioCodec != null) + command.append(" -codec:a ").append(audioCodec); + if (audioSampleRate != null) + command.append(" -ar ").append(audioSampleRate); + if (audioChannels != null) + command.append(" -ac ").append(audioChannels); + if (audioBitRate != null) + command.append(" -b:a ").append(audioBitRate); + if (audioQuality != null) + command.append(" -qscale:a ").append(audioQuality); + + if (!audioEnabled) + command.append(" -an"); + + // ---------------------------------------------------- + // Subtitle Options + // ---------------------------------------------------- + + if (subtitleCodec != null) + command.append(" -codec:s ").append(subtitleCodec); + + if (!subtitleEnabled) + command.append(" -sn"); + + command.append(' ').append(output); + return command.toString().trim(); + } +} \ No newline at end of file diff --git a/test/zutil/osal/app/ffmpeg/FFmpegInputTest.java b/test/zutil/osal/app/ffmpeg/FFmpegInputTest.java new file mode 100644 index 0000000..acc3a78 --- /dev/null +++ b/test/zutil/osal/app/ffmpeg/FFmpegInputTest.java @@ -0,0 +1,56 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021 Ziver Koc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package zutil.osal.app.ffmpeg; + +import org.junit.Test; + +import static org.junit.Assert.*; + +public class FFmpegInputTest { + + @Test + public void onlyInput() { + FFmpegInput ffmpegInput = new FFmpegInput("iTest.mp4"); + + assertEquals("-i iTest.mp4", ffmpegInput.buildCommand()); + } + + @Test + public void options() { + FFmpegInput ffmpegInput = new FFmpegInput("iTest.mp4"); + ffmpegInput.setDuration(10.1f); + ffmpegInput.setStartPosition(9.1f); + ffmpegInput.setEndPosition(20.1f); + + ffmpegInput.setAudioEnabled(false); + + ffmpegInput.setSubtitleEnabled(false); + + assertEquals("-ss 9.1 -to 20.1 -t 10.1" + + " -an" + + " -sn" + + " -i iTest.mp4", ffmpegInput.buildCommand()); + } +} \ No newline at end of file diff --git a/test/zutil/osal/app/ffmpeg/FFmpegOutputTest.java b/test/zutil/osal/app/ffmpeg/FFmpegOutputTest.java new file mode 100644 index 0000000..d065b18 --- /dev/null +++ b/test/zutil/osal/app/ffmpeg/FFmpegOutputTest.java @@ -0,0 +1,74 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021 Ziver Koc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package zutil.osal.app.ffmpeg; + +import org.junit.Test; + +import static org.junit.Assert.*; + +public class FFmpegOutputTest { + + @Test + public void onlyOutput() { + FFmpegOutput ffmpegOutput = new FFmpegOutput("oTest.mp4"); + + assertEquals("oTest.mp4", ffmpegOutput.buildCommand()); + } + + + @Test + public void options() { + FFmpegOutput ffmpegOutput = new FFmpegOutput("oTest.mp4"); + ffmpegOutput.setDuration(10.1f); + ffmpegOutput.setStartPosition(9.1f); + ffmpegOutput.setEndPosition(20.1f); + ffmpegOutput.setTargetFileSize(1000); + ffmpegOutput.setEncodingPass(2); + + ffmpegOutput.setVideoCodec(FFmpegConstants.FFmpegVideoCodec.libx264); + ffmpegOutput.setVideoFrameRate(29.8f); + ffmpegOutput.setVideoResolution(320, 240); + ffmpegOutput.setVideoBitRate(300_000); + ffmpegOutput.setVideoQuality(22); + + ffmpegOutput.setAudioCodec(FFmpegConstants.FFmpegAudioCodec.libmp3lame); + ffmpegOutput.setAudioSampleRate(48_000); + ffmpegOutput.setAudioChannels(6); + ffmpegOutput.setAudioBitRate(360_000); + ffmpegOutput.setAudioQuality(23); + ffmpegOutput.setAudioEnabled(false); + + ffmpegOutput.setSubtitleCodec(FFmpegConstants.FFmpegSubtitleCodec.subrip); + ffmpegOutput.setSubtitleEnabled(false); + + assertEquals("-ss 9.1 -to 20.1 -t 10.1 -fs 1000 -pass 2" + + " -codec:v libx264 -frames 29.8 -filter:v scale=320:240 -b:v 300000 -qscale:v 22" + + " -codec:a libmp3lame -ar 48000 -ac 6 -b:a 360000 -qscale:a 23 -an" + + " -codec:s subrip -sn" + + " oTest.mp4", + ffmpegOutput.buildCommand()); + } + +} \ No newline at end of file diff --git a/test/zutil/osal/app/ffmpeg/FFmpegTest.java b/test/zutil/osal/app/ffmpeg/FFmpegTest.java new file mode 100644 index 0000000..fccf1ce --- /dev/null +++ b/test/zutil/osal/app/ffmpeg/FFmpegTest.java @@ -0,0 +1,63 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021 Ziver Koc + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package zutil.osal.app.ffmpeg; + +import org.junit.Test; +import zutil.osal.app.ffmpeg.FFmpegConstants.*; + +import static org.junit.Assert.*; + + +public class FFmpegTest { + + @Test + public void noArgs() { + FFmpeg ffmpeg = new FFmpeg(); + ffmpeg.addInput(new FFmpegInput("iTest.mp4")); + ffmpeg.addOutput(new FFmpegOutput("oTest.mp4")); + + assertEquals("ffmpeg -i iTest.mp4 oTest.mp4", ffmpeg.buildCommand()); + } + + @Test + public void setLogLevel() { + FFmpeg ffmpeg = new FFmpeg(); + ffmpeg.setLogLevel(FFmpegLogLevel.ERROR); + ffmpeg.addInput(new FFmpegInput("iTest.mp4")); + ffmpeg.addOutput(new FFmpegOutput("oTest.mp4")); + + assertEquals("ffmpeg -loglevel error -i iTest.mp4 oTest.mp4", ffmpeg.buildCommand()); + } + + @Test + public void enableOutputOverwrite() { + FFmpeg ffmpeg = new FFmpeg(); + ffmpeg.enableOutputOverwrite(true); + ffmpeg.addInput(new FFmpegInput("iTest.mp4")); + ffmpeg.addOutput(new FFmpegOutput("oTest.mp4")); + + assertEquals("ffmpeg -y -i iTest.mp4 oTest.mp4", ffmpeg.buildCommand()); + } +} \ No newline at end of file