Skip to content

Commit

Permalink
Merge pull request #407 from kokorin/develop
Browse files Browse the repository at this point in the history
Merge develop to master
  • Loading branch information
kokorin authored Aug 29, 2024
2 parents b503d1f + d6a9051 commit 6c2d067
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 60 deletions.
12 changes: 6 additions & 6 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,22 +42,22 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4

- uses: actions/setup-java@v3
- uses: actions/setup-java@v4
with:
distribution: 'adopt'
java-version: 17
distribution: 'temurin'
java-version: 21

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main

- uses: actions/cache@v3
- uses: actions/cache@v4
with:
# be careful not to include ~/.m2/settings.xml which contains credentials
path: |
Expand All @@ -70,4 +70,4 @@ jobs:
run: bash mvnw clean install -B -DskipTests

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
uses: github/codeql-action/analyze@v3
8 changes: 4 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ jobs:
steps:
- uses: actions/checkout@v4

- uses: actions/setup-java@v3
- uses: actions/setup-java@v4
with:
distribution: 'adopt'
java-version: 11
distribution: 'temurin'
java-version: 21

- uses: actions/cache@v3
- uses: actions/cache@v4
with:
# be careful not to include ~/.m2/settings.xml which contains credentials
path: |
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/sonar-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,22 @@ jobs:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis

- name: Set up JDK
uses: actions/setup-java@v3
uses: actions/setup-java@v4
with:
distribution: 'adopt'
java-version: 17
distribution: 'temurin'
java-version: 21

- name: Install ffmpeg on Ubuntu
run: sudo apt-get update && sudo apt-get install -y ffmpeg && ffmpeg -version

- name: Cache SonarCloud packages
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ~/.sonar/cache
key: ${{ runner.os }}-sonar
restore-keys: ${{ runner.os }}-sonar

- uses: actions/cache@v3
- uses: actions/cache@v4
with:
# be careful not to include ~/.m2/settings.xml which contains credentials
path: |
Expand Down
43 changes: 19 additions & 24 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,23 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ ubuntu-latest, macos-latest, windows-latest ]
java-version: [ 8, 11, 17 ]
os:
- ubuntu-latest
- macos-latest
- windows-latest
fail-fast: false

steps:
- uses: actions/checkout@v4

- name: Set up JDK
uses: actions/setup-java@v3
uses: actions/setup-java@v4
with:
distribution: 'adopt'
java-version: ${{ matrix.java-version }}
distribution: 'temurin'
java-version: 21

- name: Cache Maven Packages
uses: actions/cache@v3
uses: actions/cache@v4
with:
# be careful not to include ~/.m2/settings.xml which contains credentials
path: |
Expand All @@ -49,51 +51,44 @@ jobs:
restore-keys: ${{ runner.os }}-m2

- name: Cache Test Artifacts
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: |
.artifacts
key: ${{ runner.os }}-artifacts-${{ hashFiles('**/Artifacts.java') }}

- name: Install ffmpeg on Ubuntu
run: sudo apt-get update && sudo apt-get install -y ffmpeg && ffmpeg -version
run: sudo apt-get update && sudo apt-get install -y ffmpeg
if: startsWith(matrix.os, 'ubuntu')

- name: Install ffmpeg on MacOS
run: brew install ffmpeg && ls -lhtr /usr/local/opt/ffmpeg/ && ffmpeg -version
run: brew install ffmpeg
if: startsWith(matrix.os, 'macos')

- name: Install ffmpeg on Windows
run: choco install ffmpeg && ffmpeg -version
run: choco install ffmpeg
if: startsWith(matrix.os, 'windows')

- name: Build on Ubuntu
run: bash mvnw clean package -B
if: startsWith(matrix.os, 'ubuntu')
- run: ffmpeg -version

- name: Build on MacOS
run: bash mvnw clean package -B
if: startsWith(matrix.os, 'macos')

- name: Build on Windows
- name: Build and test
run: ./mvnw clean package -B
if: startsWith(matrix.os, 'windows')

test-release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up JDK
uses: actions/setup-java@v3
uses: actions/setup-java@v4
with:
distribution: 'adopt'
java-version: 11
distribution: 'temurin'
java-version: 21

- name: Set up RANDOM GPG key
run: gpg --quick-generate-key --batch --passphrase '' test42

- uses: actions/cache@v3
- uses: actions/cache@v4
with:
# be careful not to include ~/.m2/settings.xml which contains credentials
path: |
Expand Down
10 changes: 5 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,13 @@
<dependency>
<groupId>com.grack</groupId>
<artifactId>nanojson</artifactId>
<version>1.7</version>
<version>1.9</version>
</dependency>

<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.10</version>
<version>1.5.7</version>
<scope>test</scope>
</dependency>

Expand Down Expand Up @@ -150,7 +150,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.1</version>
<version>3.3.1</version>
<executions>
<execution>
<id>attach-sources</id>
Expand Down Expand Up @@ -180,7 +180,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>3.0.1</version>
<version>3.2.5</version>
<executions>
<execution>
<id>sign-artifacts</id>
Expand Down Expand Up @@ -241,7 +241,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.1.2</version>
<version>3.5.0</version>
<configuration>
<indentSize>4</indentSize>
<configLocation>checkstyle.xml</configLocation>
Expand Down
22 changes: 14 additions & 8 deletions src/main/java/com/github/kokorin/jaffree/util/ParseUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@
*/
@SuppressWarnings("checkstyle:MagicNumber")
public final class ParseUtil {

private static final String KBYTES_SUFFIX = "kB";
private static final String[] KBYTES_SUFFIXES = {"kB", "KiB"};
private static final String KBITS_PER_SECOND_SUFFIX = "kbits/s";
private static final String SPEED_SUFFIX = "x";
private static final String PERCENT_SUFFIX = "%";
Expand Down Expand Up @@ -78,33 +77,40 @@ public static Double parseDouble(final String value) {
}

/**
* Parses size in kilobytes without exception.
* Parses size in kibibytes without exception.
*
* @param value string to parse
* @return parsed long or null if value can't be parsed
*/
public static Long parseSizeInBytes(final String value) {
Long result = parseSizeInKiloBytes(value);
Long result = parseSizeInKibiBytes(value);

if (result == null) {
return null;
}

return result * 1000;
return result * 1024;
}

/**
* Parses size in kilobytes without exception.
* Parses size in kibibytes without exception.
*
* @param value string to parse
* @return parsed long or null if value can't be parsed
*/
public static Long parseSizeInKiloBytes(final String value) {
public static Long parseSizeInKibiBytes(final String value) {
if (value == null || value.isEmpty()) {
return null;
}

return parseLongWithSuffix(value.trim(), KBYTES_SUFFIX);
final String trimmedValue = value.trim();
Long result = null;

for (int i = 0; i < KBYTES_SUFFIXES.length && result == null; i++) {
result = parseLongWithSuffix(trimmedValue, KBYTES_SUFFIXES[i]);
}

return result;
}

/**
Expand Down
56 changes: 52 additions & 4 deletions src/test/java/com/github/kokorin/jaffree/ffmpeg/FFmpegTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
Expand Down Expand Up @@ -240,6 +241,43 @@ public void onProgress(FFmpegProgress progress) {
.execute();
}

@Test
public void testFrameCountingWithStreamCopyAndProgressListener() throws Exception {
final AtomicBoolean ffmpegHasStreamCopyBug = new AtomicBoolean(false);

final OutputListener outputListener = message -> {
// Don't check the frame count in at FFmpeg 6.1.x and 7.0.x due to a stream copy bug,
// which is addressed on the master branch, see:
// https://github.com/FFmpeg/FFmpeg/commit/598f541ba49cb682dcd74e86858c9a4985149e1f
if (message.contains("ffmpeg version 6.1") || message.contains("ffmpeg version 7.0")) {
ffmpegHasStreamCopyBug.set(true);
}
};

final AtomicReference<Long> frameRef = new AtomicReference<>();

final ProgressListener progressListener = new ProgressListener() {
@Override
public void onProgress(FFmpegProgress progress) {
System.out.println(progress);
frameRef.set(progress.getFrame());
}
};

final FFmpegResult result = FFmpeg.atPath(Config.FFMPEG_BIN)
.addInput(UrlInput.fromPath(Artifacts.VIDEO_NUT))
.addOutput(new NullOutput())
.setOutputListener(outputListener)
.setProgressListener(progressListener)
.execute();

if (ffmpegHasStreamCopyBug.get()) {
LOGGER.warn("Detected buggy FFmpeg version, frame count not checked");
} else {
assertNotNull(frameRef.get());
}
}

@Test
public void testForceStopWithThreadInterruption() throws Exception {
Path tempDir = Files.createTempDirectory("jaffree");
Expand Down Expand Up @@ -519,14 +557,24 @@ public void testExceptionIsThrownIfFfmpegExitsWithError() {
.addOutput(new NullOutput())
.execute();
} catch (JaffreeAbnormalExitException e) {
assertEquals("Process execution has ended with non-zero status: 1. Check logs for detailed error message.", e.getMessage());
assertEquals(1, e.getProcessErrorLogMessages().size());
assertEquals("[error] non_existent.mp4: No such file or directory", e.getProcessErrorLogMessages().get(0).message);
if ("Process execution has ended with non-zero status: 254. Check logs for detailed error message.".equals(e.getMessage())) {
// FFmpeg 6+
assertEquals(3, e.getProcessErrorLogMessages().size());
assertEquals("[error] Error opening input file non_existent.mp4.", e.getProcessErrorLogMessages().get(1).message);
} else if ("Process execution has ended with non-zero status: -2. Check logs for detailed error message.".equals(e.getMessage())) {
// FFmpeg 7
assertEquals(3, e.getProcessErrorLogMessages().size());
assertEquals("[error] Error opening input file non_existent.mp4.", e.getProcessErrorLogMessages().get(1).message);
} else if ("Process execution has ended with non-zero status: 1. Check logs for detailed error message.".equals(e.getMessage())) {
assertEquals(1, e.getProcessErrorLogMessages().size());
assertEquals("[error] non_existent.mp4: No such file or directory", e.getProcessErrorLogMessages().get(0).message);
} else {
fail("Unknown FFmpeg output format (update test code!): " + e.getMessage());
}
return;
}

fail("JaffreeAbnormalExitException should have been thrown!");

}

@Test
Expand Down
19 changes: 15 additions & 4 deletions src/test/java/com/github/kokorin/jaffree/util/ParseUtilTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,25 @@ public void parseLogLevel() {
}

@Test
public void parsResult() throws Exception {
public void parseKibiByteFormats() {
final Long oldFormat = ParseUtil.parseSizeInKibiBytes("2904kB");
Assert.assertEquals(2904L, oldFormat.longValue());

final Long newFormat = ParseUtil.parseSizeInKibiBytes("2904KiB");
Assert.assertEquals(2904L, newFormat.longValue());

final Long unknownFormat = ParseUtil.parseSizeInKibiBytes("2904KB");
Assert.assertNull(unknownFormat);
}

@Test
public void parseResult() throws Exception {
String value = "video:1417kB audio:113kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown";
FFmpegResult result = ParseUtil.parseResult(value);

Assert.assertNotNull(result);
Assert.assertEquals((Long) 1_417_000L, result.getVideoSize());
Assert.assertEquals((Long) 113_000L, result.getAudioSize());
Assert.assertEquals((Long) 1_451_008L, result.getVideoSize());
Assert.assertEquals((Long) 115_712L, result.getAudioSize());
Assert.assertEquals((Long) 0L, result.getSubtitleSize());
Assert.assertEquals((Long) 0L, result.getOtherStreamsSize());
Assert.assertEquals((Long) 0L, result.getGlobalHeadersSize());
Expand Down Expand Up @@ -98,5 +110,4 @@ public void parseResultWhichDoesntContainResult() throws Exception {

Assert.assertNull(result);
}

}

0 comments on commit 6c2d067

Please sign in to comment.