update android api, fixes #1
parent
18f6dd0099
commit
a1e7a0b9da
@ -1,2 +1 @@ |
|||||||
<manifest package="com.arthenica.ffmpegkit"> |
<manifest package="com.arthenica.ffmpegkit" /> |
||||||
</manifest> |
|
||||||
|
@ -0,0 +1,135 @@ |
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021 Taner Sener |
||||||
|
* |
||||||
|
* This file is part of FFmpegKit. |
||||||
|
* |
||||||
|
* FFmpegKit is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Lesser General Public License as published by |
||||||
|
* the Free Software Foundation, either version 3 of the License, or |
||||||
|
* (at your option) any later version. |
||||||
|
* |
||||||
|
* FFmpegKit is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Lesser General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Lesser General Public License |
||||||
|
* along with FFmpegKit. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/ |
||||||
|
|
||||||
|
#include <sys/stat.h> |
||||||
|
#include <stdlib.h> |
||||||
|
#include <unistd.h> |
||||||
|
|
||||||
|
#include "config.h" |
||||||
|
#include "libavformat/avformat.h" |
||||||
|
#include "libavutil/avstring.h" |
||||||
|
|
||||||
|
#include "saf_wrapper.h" |
||||||
|
|
||||||
|
/** JNI wrapper in ffmpegkit.c */ |
||||||
|
void closeParcelFileDescriptor(int fd); |
||||||
|
|
||||||
|
// in these wrappers, we call the original functions, so we remove the shadow defines
|
||||||
|
#undef avio_closep |
||||||
|
#undef avformat_close_input |
||||||
|
#undef avio_open |
||||||
|
#undef avio_open2 |
||||||
|
#undef avformat_open_input |
||||||
|
|
||||||
|
static int fd_read_packet(void* opaque, uint8_t* buf, int buf_size) { |
||||||
|
int fd = (int)opaque; |
||||||
|
return read(fd, buf, buf_size); |
||||||
|
} |
||||||
|
|
||||||
|
static int fd_write_packet(void* opaque, uint8_t* buf, int buf_size) { |
||||||
|
int fd = (int)opaque; |
||||||
|
return write(fd, buf, buf_size); |
||||||
|
} |
||||||
|
|
||||||
|
static int64_t fd_seek(void *opaque, int64_t offset, int whence) { |
||||||
|
int fd = (int)opaque; |
||||||
|
|
||||||
|
if (fd < 0) { |
||||||
|
return AVERROR(EINVAL); |
||||||
|
} |
||||||
|
|
||||||
|
int64_t ret; |
||||||
|
if (whence == AVSEEK_SIZE) { |
||||||
|
struct stat st; |
||||||
|
ret = fstat(fd, &st); |
||||||
|
return ret < 0 ? AVERROR(errno) : (S_ISFIFO(st.st_mode) ? 0 : st.st_size); |
||||||
|
} |
||||||
|
|
||||||
|
ret = lseek(fd, offset, whence); |
||||||
|
|
||||||
|
return ret < 0 ? AVERROR(errno) : ret; |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
* returns NULL if the filename is not of expected format (e.g. 'saf:72/video.md4') |
||||||
|
*/ |
||||||
|
static AVIOContext *create_fd_avio_context(const char *filename, int flags) { |
||||||
|
union {int fd; void* opaque;} fdunion; |
||||||
|
fdunion.fd = -1; |
||||||
|
const char *fd_ptr = NULL; |
||||||
|
if (av_strstart(filename, "saf:", &fd_ptr)) { |
||||||
|
char *final; |
||||||
|
fdunion.fd = strtol(fd_ptr, &final, 10); |
||||||
|
if (fd_ptr == final) { /* No digits found */ |
||||||
|
fdunion.fd = -1; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (fdunion.fd >= 0) { |
||||||
|
int write_flag = flags & AVIO_FLAG_WRITE ? 1 : 0; |
||||||
|
return avio_alloc_context(av_malloc(4096), 4096, write_flag, fdunion.opaque, fd_read_packet, write_flag ? fd_write_packet : NULL, fd_seek); |
||||||
|
} |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void close_fd_avio_context(AVIOContext *ctx) { |
||||||
|
if (fd_seek(ctx->opaque, 0, AVSEEK_SIZE) >= 0) { |
||||||
|
int fd = (int)ctx->opaque; |
||||||
|
close(fd); |
||||||
|
closeParcelFileDescriptor(fd); |
||||||
|
} |
||||||
|
ctx->opaque = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
int android_avformat_open_input(AVFormatContext **ps, const char *filename, |
||||||
|
ff_const59 AVInputFormat *fmt, AVDictionary **options) { |
||||||
|
if (!(*ps) && !(*ps = avformat_alloc_context())) |
||||||
|
return AVERROR(ENOMEM); |
||||||
|
|
||||||
|
(*ps)->pb = create_fd_avio_context(filename, AVIO_FLAG_READ); |
||||||
|
|
||||||
|
return avformat_open_input(ps, filename, fmt, options); |
||||||
|
} |
||||||
|
|
||||||
|
int android_avio_open2(AVIOContext **s, const char *filename, int flags, |
||||||
|
const AVIOInterruptCB *int_cb, AVDictionary **options) { |
||||||
|
AVIOContext *fd_context = create_fd_avio_context(filename, flags); |
||||||
|
|
||||||
|
if (fd_context) { |
||||||
|
*s = fd_context; |
||||||
|
return 0; |
||||||
|
} |
||||||
|
return avio_open2(s, filename, flags, int_cb, options); |
||||||
|
} |
||||||
|
|
||||||
|
int android_avio_open(AVIOContext **s, const char *url, int flags) { |
||||||
|
return android_avio_open2(s, url, flags, NULL, NULL); |
||||||
|
} |
||||||
|
|
||||||
|
int android_avio_closep(AVIOContext **s) { |
||||||
|
close_fd_avio_context(*s); |
||||||
|
return avio_closep(s); |
||||||
|
} |
||||||
|
|
||||||
|
void android_avformat_close_input(AVFormatContext **ps) { |
||||||
|
if (*ps && (*ps)->pb) { |
||||||
|
close_fd_avio_context((*ps)->pb); |
||||||
|
} |
||||||
|
avformat_close_input(ps); |
||||||
|
} |
@ -0,0 +1,46 @@ |
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021 Taner Sener |
||||||
|
* |
||||||
|
* This file is part of FFmpegKit. |
||||||
|
* |
||||||
|
* FFmpegKit is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Lesser General Public License as published by |
||||||
|
* the Free Software Foundation, either version 3 of the License, or |
||||||
|
* (at your option) any later version. |
||||||
|
* |
||||||
|
* FFmpegKit is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Lesser General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Lesser General Public License |
||||||
|
* along with FFmpegKit. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef FFMPEG_KIT_SAF_WRAPPER_H |
||||||
|
#define FFMPEG_KIT_SAF_WRAPPER_H |
||||||
|
|
||||||
|
/*
|
||||||
|
* These wrappers are intended to be used instead of the ffmpeg apis. |
||||||
|
* You don't even need to change the source to call them. |
||||||
|
* Instead, we redefine the public api names so that the wrapper be used. |
||||||
|
*/ |
||||||
|
|
||||||
|
int android_avio_closep(AVIOContext **s); |
||||||
|
#define avio_closep android_avio_closep |
||||||
|
|
||||||
|
void android_avformat_close_input(AVFormatContext **s); |
||||||
|
#define avformat_close_input android_avformat_close_input |
||||||
|
|
||||||
|
int android_avio_open(AVIOContext **s, const char *url, int flags); |
||||||
|
#define avio_open android_avio_open |
||||||
|
|
||||||
|
int android_avio_open2(AVIOContext **s, const char *url, int flags, |
||||||
|
const AVIOInterruptCB *int_cb, AVDictionary **options); |
||||||
|
#define avio_open2 android_avio_open2 |
||||||
|
|
||||||
|
int android_avformat_open_input(AVFormatContext **ps, const char *filename, |
||||||
|
ff_const59 AVInputFormat *fmt, AVDictionary **options); |
||||||
|
#define avformat_open_input android_avformat_open_input |
||||||
|
|
||||||
|
#endif //FFMPEG_KIT_SAF_WRAPPER_H
|
@ -0,0 +1,197 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2021 Taner Sener |
||||||
|
* |
||||||
|
* This file is part of FFmpegKit. |
||||||
|
* |
||||||
|
* FFmpegKit is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Lesser General Public License as published by |
||||||
|
* the Free Software Foundation, either version 3 of the License, or |
||||||
|
* (at your option) any later version. |
||||||
|
* |
||||||
|
* FFmpegKit is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Lesser General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Lesser General Public License |
||||||
|
* along with FFmpegKit. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/ |
||||||
|
|
||||||
|
package com.arthenica.ffmpegkit; |
||||||
|
|
||||||
|
import com.arthenica.smartexception.java.Exceptions; |
||||||
|
|
||||||
|
import java.util.Date; |
||||||
|
import java.util.Optional; |
||||||
|
import java.util.Queue; |
||||||
|
import java.util.concurrent.ConcurrentLinkedQueue; |
||||||
|
import java.util.concurrent.Future; |
||||||
|
import java.util.concurrent.atomic.AtomicLong; |
||||||
|
import java.util.function.BinaryOperator; |
||||||
|
import java.util.function.Function; |
||||||
|
import java.util.function.Supplier; |
||||||
|
import java.util.stream.Stream; |
||||||
|
|
||||||
|
public abstract class AbstractSession implements Session { |
||||||
|
|
||||||
|
/** |
||||||
|
* Generates ids for execute sessions. |
||||||
|
*/ |
||||||
|
private static final AtomicLong sessionIdGenerator = new AtomicLong(1); |
||||||
|
|
||||||
|
protected final ExecuteCallback executeCallback; |
||||||
|
protected final LogCallback logCallback; |
||||||
|
protected final StatisticsCallback statisticsCallback; |
||||||
|
protected final long sessionId; |
||||||
|
protected final Date createTime; |
||||||
|
protected Date startTime; |
||||||
|
protected Date endTime; |
||||||
|
protected final String[] arguments; |
||||||
|
protected final Queue<Log> logs; |
||||||
|
protected Future<?> future; |
||||||
|
protected SessionState state; |
||||||
|
protected int returnCode; |
||||||
|
protected String failStackTrace; |
||||||
|
|
||||||
|
public AbstractSession(final String[] arguments, |
||||||
|
final ExecuteCallback executeCallback, |
||||||
|
final LogCallback logCallback, |
||||||
|
final StatisticsCallback statisticsCallback) { |
||||||
|
this.sessionId = sessionIdGenerator.getAndIncrement(); |
||||||
|
this.createTime = new Date(); |
||||||
|
this.startTime = null; |
||||||
|
this.arguments = arguments; |
||||||
|
this.executeCallback = executeCallback; |
||||||
|
this.logCallback = logCallback; |
||||||
|
this.statisticsCallback = statisticsCallback; |
||||||
|
this.logs = new ConcurrentLinkedQueue<>(); |
||||||
|
this.future = null; |
||||||
|
this.state = SessionState.CREATED; |
||||||
|
this.returnCode = ReturnCode.NOT_SET; |
||||||
|
this.failStackTrace = null; |
||||||
|
} |
||||||
|
|
||||||
|
public ExecuteCallback getExecuteCallback() { |
||||||
|
return executeCallback; |
||||||
|
} |
||||||
|
|
||||||
|
public LogCallback getLogCallback() { |
||||||
|
return logCallback; |
||||||
|
} |
||||||
|
|
||||||
|
public StatisticsCallback getStatisticsCallback() { |
||||||
|
return statisticsCallback; |
||||||
|
} |
||||||
|
|
||||||
|
public long getSessionId() { |
||||||
|
return sessionId; |
||||||
|
} |
||||||
|
|
||||||
|
public Date getCreateTime() { |
||||||
|
return createTime; |
||||||
|
} |
||||||
|
|
||||||
|
public Date getStartTime() { |
||||||
|
return startTime; |
||||||
|
} |
||||||
|
|
||||||
|
public Date getEndTime() { |
||||||
|
return endTime; |
||||||
|
} |
||||||
|
|
||||||
|
public long getDuration() { |
||||||
|
final Date startTime = this.startTime; |
||||||
|
final Date endTime = this.endTime; |
||||||
|
if (startTime != null && endTime != null) { |
||||||
|
return (endTime.getTime() - startTime.getTime()); |
||||||
|
} |
||||||
|
|
||||||
|
return -1; |
||||||
|
} |
||||||
|
|
||||||
|
public String[] getArguments() { |
||||||
|
return arguments; |
||||||
|
} |
||||||
|
|
||||||
|
public String getCommand() { |
||||||
|
return FFmpegKit.argumentsToString(arguments); |
||||||
|
} |
||||||
|
|
||||||
|
public Queue<Log> getLogs() { |
||||||
|
return logs; |
||||||
|
} |
||||||
|
|
||||||
|
public Stream<Log> getLogsAsStream() { |
||||||
|
return logs.stream(); |
||||||
|
} |
||||||
|
|
||||||
|
public String getLogsAsString() { |
||||||
|
final Optional<String> concatenatedStringOption = logs.stream().map(new Function<Log, String>() { |
||||||
|
@Override |
||||||
|
public String apply(final Log log) { |
||||||
|
return log.getMessage(); |
||||||
|
} |
||||||
|
}).reduce(new BinaryOperator<String>() { |
||||||
|
@Override |
||||||
|
public String apply(final String s1, final String s2) { |
||||||
|
return s1 + s2; |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
return concatenatedStringOption.orElseGet(new Supplier<String>() { |
||||||
|
|
||||||
|
@Override |
||||||
|
public String get() { |
||||||
|
return ""; |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
public SessionState getState() { |
||||||
|
return state; |
||||||
|
} |
||||||
|
|
||||||
|
public int getReturnCode() { |
||||||
|
return returnCode; |
||||||
|
} |
||||||
|
|
||||||
|
public String getFailStackTrace() { |
||||||
|
return failStackTrace; |
||||||
|
} |
||||||
|
|
||||||
|
public void addLog(final Log log) { |
||||||
|
this.logs.add(log); |
||||||
|
} |
||||||
|
|
||||||
|
public Future<?> getFuture() { |
||||||
|
return future; |
||||||
|
} |
||||||
|
|
||||||
|
public void setFuture(final Future<?> future) { |
||||||
|
this.future = future; |
||||||
|
} |
||||||
|
|
||||||
|
public void startRunning() { |
||||||
|
this.state = SessionState.RUNNING; |
||||||
|
this.startTime = new Date(); |
||||||
|
} |
||||||
|
|
||||||
|
public void complete(final int returnCode) { |
||||||
|
this.returnCode = returnCode; |
||||||
|
this.state = SessionState.COMPLETED; |
||||||
|
this.endTime = new Date(); |
||||||
|
} |
||||||
|
|
||||||
|
public void fail(final Exception exception) { |
||||||
|
this.failStackTrace = Exceptions.getStackTraceString(exception); |
||||||
|
this.state = SessionState.FAILED; |
||||||
|
this.endTime = new Date(); |
||||||
|
} |
||||||
|
|
||||||
|
public void cancel() { |
||||||
|
if (state == SessionState.RUNNING) { |
||||||
|
FFmpegKit.cancel(sessionId); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,93 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2020-2021 Taner Sener |
||||||
|
* |
||||||
|
* This file is part of FFmpegKit. |
||||||
|
* |
||||||
|
* FFmpegKit is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Lesser General Public License as published by |
||||||
|
* the Free Software Foundation, either version 3 of the License, or |
||||||
|
* (at your option) any later version. |
||||||
|
* |
||||||
|
* FFmpegKit is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Lesser General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Lesser General Public License |
||||||
|
* along with FFmpegKit. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/ |
||||||
|
|
||||||
|
package com.arthenica.ffmpegkit; |
||||||
|
|
||||||
|
import java.util.Queue; |
||||||
|
import java.util.concurrent.ConcurrentLinkedQueue; |
||||||
|
import java.util.stream.Stream; |
||||||
|
|
||||||
|
/** |
||||||
|
* <p>An FFmpeg execute session. |
||||||
|
*/ |
||||||
|
public class FFmpegSession extends AbstractSession implements Session { |
||||||
|
private final Queue<Statistics> statistics; |
||||||
|
|
||||||
|
public FFmpegSession(final String[] arguments, |
||||||
|
final ExecuteCallback executeCallback, |
||||||
|
final LogCallback logCallback, |
||||||
|
final StatisticsCallback statisticsCallback) { |
||||||
|
super(arguments, executeCallback, logCallback, statisticsCallback); |
||||||
|
|
||||||
|
this.statistics = new ConcurrentLinkedQueue<>(); |
||||||
|
} |
||||||
|
|
||||||
|
public Queue<Statistics> getStatistics() { |
||||||
|
return statistics; |
||||||
|
} |
||||||
|
|
||||||
|
public Stream<Statistics> getStatisticsAsStream() { |
||||||
|
return statistics.stream(); |
||||||
|
} |
||||||
|
|
||||||
|
public void addStatistics(final Statistics statistics) { |
||||||
|
this.statistics.add(statistics); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean isFFmpeg() { |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean isFFprobe() { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
final StringBuilder stringBuilder = new StringBuilder(); |
||||||
|
|
||||||
|
stringBuilder.append("FFmpegSession{"); |
||||||
|
stringBuilder.append("sessionId="); |
||||||
|
stringBuilder.append(sessionId); |
||||||
|
stringBuilder.append(", createTime="); |
||||||
|
stringBuilder.append(createTime); |
||||||
|
stringBuilder.append(", startTime="); |
||||||
|
stringBuilder.append(startTime); |
||||||
|
stringBuilder.append(", endTime="); |
||||||
|
stringBuilder.append(endTime); |
||||||
|
stringBuilder.append(", arguments="); |
||||||
|
stringBuilder.append(FFmpegKit.argumentsToString(arguments)); |
||||||
|
stringBuilder.append(", logs="); |
||||||
|
stringBuilder.append(getLogsAsString()); |
||||||
|
stringBuilder.append(", state="); |
||||||
|
stringBuilder.append(state); |
||||||
|
stringBuilder.append(", returnCode="); |
||||||
|
stringBuilder.append(returnCode); |
||||||
|
stringBuilder.append(", failStackTrace="); |
||||||
|
stringBuilder.append('\''); |
||||||
|
stringBuilder.append(failStackTrace); |
||||||
|
stringBuilder.append('\''); |
||||||
|
stringBuilder.append('}'); |
||||||
|
|
||||||
|
return stringBuilder.toString(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,98 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2020-2021 Taner Sener |
||||||
|
* |
||||||
|
* This file is part of FFmpegKit. |
||||||
|
* |
||||||
|
* FFmpegKit is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Lesser General Public License as published by |
||||||
|
* the Free Software Foundation, either version 3 of the License, or |
||||||
|
* (at your option) any later version. |
||||||
|
* |
||||||
|
* FFmpegKit is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Lesser General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Lesser General Public License |
||||||
|
* along with FFmpegKit. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/ |
||||||
|
|
||||||
|
package com.arthenica.ffmpegkit; |
||||||
|
|
||||||
|
import java.text.MessageFormat; |
||||||
|
import java.util.LinkedList; |
||||||
|
import java.util.Queue; |
||||||
|
import java.util.stream.Stream; |
||||||
|
|
||||||
|
/** |
||||||
|
* <p>An FFprobe execute session. |
||||||
|
*/ |
||||||
|
public class FFprobeSession extends AbstractSession implements Session { |
||||||
|
|
||||||
|
public FFprobeSession(final String[] arguments, |
||||||
|
final ExecuteCallback executeCallback, |
||||||
|
final LogCallback logCallback, |
||||||
|
final StatisticsCallback statisticsCallback) { |
||||||
|
super(arguments, executeCallback, logCallback, statisticsCallback); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Queue<Statistics> getStatistics() { |
||||||
|
return new LinkedList<>(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Stream<Statistics> getStatisticsAsStream() { |
||||||
|
return new LinkedList<Statistics>().stream(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void addStatistics(final Statistics statistics) { |
||||||
|
/* |
||||||
|
* ffprobe does not support statistics. |
||||||
|
* So, this method should never have been called. |
||||||
|
*/ |
||||||
|
android.util.Log.w(FFmpegKitConfig.TAG, MessageFormat.format("FFprobe execute session {0} received statistics.", sessionId)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean isFFmpeg() { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean isFFprobe() { |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
final StringBuilder stringBuilder = new StringBuilder(); |
||||||
|
|
||||||
|
stringBuilder.append("FFprobeSession{"); |
||||||
|
stringBuilder.append("sessionId="); |
||||||
|
stringBuilder.append(sessionId); |
||||||
|
stringBuilder.append(", createTime="); |
||||||
|
stringBuilder.append(createTime); |
||||||
|
stringBuilder.append(", startTime="); |
||||||
|
stringBuilder.append(startTime); |
||||||
|
stringBuilder.append(", endTime="); |
||||||
|
stringBuilder.append(endTime); |
||||||
|
stringBuilder.append(", arguments="); |
||||||
|
stringBuilder.append(FFmpegKit.argumentsToString(arguments)); |
||||||
|
stringBuilder.append(", logs="); |
||||||
|
stringBuilder.append(getLogsAsString()); |
||||||
|
stringBuilder.append(", state="); |
||||||
|
stringBuilder.append(state); |
||||||
|
stringBuilder.append(", returnCode="); |
||||||
|
stringBuilder.append(returnCode); |
||||||
|
stringBuilder.append(", failStackTrace="); |
||||||
|
stringBuilder.append('\''); |
||||||
|
stringBuilder.append(failStackTrace); |
||||||
|
stringBuilder.append('\''); |
||||||
|
stringBuilder.append('}'); |
||||||
|
|
||||||
|
return stringBuilder.toString(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,74 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2021 Taner Sener |
||||||
|
* |
||||||
|
* This file is part of FFmpegKit. |
||||||
|
* |
||||||
|
* FFmpegKit is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Lesser General Public License as published by |
||||||
|
* the Free Software Foundation, either version 3 of the License, or |
||||||
|
* (at your option) any later version. |
||||||
|
* |
||||||
|
* FFmpegKit is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Lesser General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Lesser General Public License |
||||||
|
* along with FFmpegKit. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/ |
||||||
|
|
||||||
|
package com.arthenica.ffmpegkit; |
||||||
|
|
||||||
|
/** |
||||||
|
* <p>A custom FFprobe execute session, which produces a <code>MediaInformation</code> object |
||||||
|
* using the output of the execution. |
||||||
|
*/ |
||||||
|
public class MediaInformationSession extends FFprobeSession implements Session { |
||||||
|
private MediaInformation mediaInformation; |
||||||
|
|
||||||
|
public MediaInformationSession(final String[] arguments, |
||||||
|
final ExecuteCallback executeCallback, |
||||||
|
final LogCallback logCallback, |
||||||
|
final StatisticsCallback statisticsCallback) { |
||||||
|
super(arguments, executeCallback, logCallback, statisticsCallback); |
||||||
|
} |
||||||
|
|
||||||
|
public MediaInformation getMediaInformation() { |
||||||
|
return mediaInformation; |
||||||
|
} |
||||||
|
|
||||||
|
public void setMediaInformation(MediaInformation mediaInformation) { |
||||||
|
this.mediaInformation = mediaInformation; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
final StringBuilder stringBuilder = new StringBuilder(); |
||||||
|
|
||||||
|
stringBuilder.append("MediaInformationSession{"); |
||||||
|
stringBuilder.append("sessionId="); |
||||||
|
stringBuilder.append(sessionId); |
||||||
|
stringBuilder.append(", createTime="); |
||||||
|
stringBuilder.append(createTime); |
||||||
|
stringBuilder.append(", startTime="); |
||||||
|
stringBuilder.append(startTime); |
||||||
|
stringBuilder.append(", endTime="); |
||||||
|
stringBuilder.append(endTime); |
||||||
|
stringBuilder.append(", arguments="); |
||||||
|
stringBuilder.append(FFmpegKit.argumentsToString(arguments)); |
||||||
|
stringBuilder.append(", logs="); |
||||||
|
stringBuilder.append(getLogsAsString()); |
||||||
|
stringBuilder.append(", state="); |
||||||
|
stringBuilder.append(state); |
||||||
|
stringBuilder.append(", returnCode="); |
||||||
|
stringBuilder.append(returnCode); |
||||||
|
stringBuilder.append(", failStackTrace="); |
||||||
|
stringBuilder.append('\''); |
||||||
|
stringBuilder.append(failStackTrace); |
||||||
|
stringBuilder.append('\''); |
||||||
|
stringBuilder.append('}'); |
||||||
|
|
||||||
|
return stringBuilder.toString(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,88 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2021 Taner Sener |
||||||
|
* |
||||||
|
* This file is part of FFmpegKit. |
||||||
|
* |
||||||
|
* FFmpegKit is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Lesser General License as published by |
||||||
|
* the Free Software Foundation, either version 3 of the License, or |
||||||
|
* (at your option) any later version. |
||||||
|
* |
||||||
|
* FFmpegKit is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Lesser General License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Lesser General License |
||||||
|
* along with FFmpegKit. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/ |
||||||
|
|
||||||
|
package com.arthenica.ffmpegkit; |
||||||
|
|
||||||
|
import java.util.Date; |
||||||
|
import java.util.Queue; |
||||||
|
import java.util.concurrent.Future; |
||||||
|
import java.util.stream.Stream; |
||||||
|
|
||||||
|
/** |
||||||
|
* <p>Interface for ffmpeg and ffprobe execute sessions. |
||||||
|
*/ |
||||||
|
public interface Session { |
||||||
|
|
||||||
|
ExecuteCallback getExecuteCallback(); |
||||||
|
|
||||||
|
LogCallback getLogCallback(); |
||||||
|
|
||||||
|
StatisticsCallback getStatisticsCallback(); |
||||||
|
|
||||||
|
long getSessionId(); |
||||||
|
|
||||||
|
Date getCreateTime(); |
||||||
|
|
||||||
|
Date getStartTime(); |
||||||
|
|
||||||
|
Date getEndTime(); |
||||||
|
|
||||||
|
long getDuration(); |
||||||
|
|
||||||
|
String[] getArguments(); |
||||||
|
|
||||||
|
String getCommand(); |
||||||
|
|
||||||
|
Queue<Log> getLogs(); |
||||||
|
|
||||||
|
Stream<Log> getLogsAsStream(); |
||||||
|
|
||||||
|
String getLogsAsString(); |
||||||
|
|
||||||
|
Queue<Statistics> getStatistics(); |
||||||
|
|
||||||
|
Stream<Statistics> getStatisticsAsStream(); |
||||||
|
|
||||||
|
SessionState getState(); |
||||||
|
|
||||||
|
int getReturnCode(); |
||||||
|
|
||||||
|
String getFailStackTrace(); |
||||||
|
|
||||||
|
void addLog(final Log log); |
||||||
|
|
||||||
|
void addStatistics(final Statistics statistics); |
||||||
|
|
||||||
|
Future<?> getFuture(); |
||||||
|
|
||||||
|
void setFuture(final Future<?> future); |
||||||
|
|
||||||
|
void startRunning(); |
||||||
|
|
||||||
|
void complete(final int returnCode); |
||||||
|
|
||||||
|
void fail(final Exception exception); |
||||||
|
|
||||||
|
boolean isFFmpeg(); |
||||||
|
|
||||||
|
boolean isFFprobe(); |
||||||
|
|
||||||
|
void cancel(); |
||||||
|
|
||||||
|
} |
@ -0,0 +1,44 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2021 Taner Sener |
||||||
|
* |
||||||
|
* This file is part of FFmpegKit. |
||||||
|
* |
||||||
|
* FFmpegKit is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU Lesser General Public License as published by |
||||||
|
* the Free Software Foundation, either version 3 of the License, or |
||||||
|
* (at your option) any later version. |
||||||
|
* |
||||||
|
* FFmpegKit is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU Lesser General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU Lesser General Public License |
||||||
|
* along with FFmpegKit. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/ |
||||||
|
|
||||||
|
package com.arthenica.ffmpegkit; |
||||||
|
|
||||||
|
import org.junit.Assert; |
||||||
|
import org.junit.Test; |
||||||
|
|
||||||
|
public class AbstractSessionTest { |
||||||
|
|
||||||
|
private static final String[] TEST_ARGUMENTS = new String[]{"argument1", "argument2"}; |
||||||
|
|
||||||
|
@Test |
||||||
|
public void getLogsAsStringTest() { |
||||||
|
final FFprobeSession ffprobeSession = new FFprobeSession(TEST_ARGUMENTS, null, null, null); |
||||||
|
|
||||||
|
String logMessage1 = "i am log one"; |
||||||
|
String logMessage2 = "i am log two"; |
||||||
|
|
||||||
|
ffprobeSession.addLog(new Log(ffprobeSession.getSessionId(), Level.AV_LOG_DEBUG, logMessage1)); |
||||||
|
ffprobeSession.addLog(new Log(ffprobeSession.getSessionId(), Level.AV_LOG_DEBUG, logMessage2)); |
||||||
|
|
||||||
|
String logsAsString = ffprobeSession.getLogsAsString(); |
||||||
|
|
||||||
|
Assert.assertEquals(logMessage1 + logMessage2, logsAsString); |
||||||
|
} |
||||||
|
|
||||||
|
} |
Loading…
Reference in new issue