Skip to content

Commit 6e27a6d

Browse files
committed
Updated JCEF to use upstream version
Moved media playback to use ffmpeg
1 parent 30a9a62 commit 6e27a6d

25 files changed

Lines changed: 1673 additions & 78 deletions

File tree

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
name: JavaSE CEF/FFmpeg Smoke
2+
3+
on:
4+
pull_request:
5+
paths:
6+
- '.github/workflows/javase-cef-ffmpeg-smoke.yml'
7+
- 'Ports/JavaSE/**'
8+
- 'maven/javase/**'
9+
- 'maven/cn1-binaries/**'
10+
- 'maven/codenameone-maven-plugin/**'
11+
- 'maven/tests/javase-cef-ffmpeg-smoke/**'
12+
- 'maven/pom.xml'
13+
- 'scripts/run-javase-cef-ffmpeg-smoke.py'
14+
- 'scripts/javase-cef-ffmpeg-smoke/**'
15+
push:
16+
branches:
17+
- master
18+
paths:
19+
- '.github/workflows/javase-cef-ffmpeg-smoke.yml'
20+
- 'Ports/JavaSE/**'
21+
- 'maven/javase/**'
22+
- 'maven/cn1-binaries/**'
23+
- 'maven/codenameone-maven-plugin/**'
24+
- 'maven/tests/javase-cef-ffmpeg-smoke/**'
25+
- 'maven/pom.xml'
26+
- 'scripts/run-javase-cef-ffmpeg-smoke.py'
27+
- 'scripts/javase-cef-ffmpeg-smoke/**'
28+
29+
jobs:
30+
javase-smoke:
31+
name: ${{ matrix.os }}
32+
strategy:
33+
fail-fast: false
34+
matrix:
35+
os: [ubuntu-latest, macos-latest, windows-latest]
36+
runs-on: ${{ matrix.os }}
37+
38+
steps:
39+
- uses: actions/checkout@v4
40+
41+
- name: Set up Java 8
42+
uses: actions/setup-java@v4
43+
with:
44+
distribution: zulu
45+
java-version: '8'
46+
47+
- name: Cache Maven dependencies
48+
uses: actions/cache@v4
49+
with:
50+
path: .m2/repository
51+
key: ${{ runner.os }}-javase-smoke-m2-${{ hashFiles('maven/**/*.xml', 'maven/**/*.pom', 'maven/tests/javase-cef-ffmpeg-smoke/**') }}
52+
restore-keys: |
53+
${{ runner.os }}-javase-smoke-m2-
54+
55+
- name: Install ffmpeg and display deps on Linux
56+
if: runner.os == 'Linux'
57+
run: |
58+
sudo apt-get update
59+
sudo apt-get install -y ffmpeg xvfb libgtk-3-0 libnss3 libxss1 libgbm1 libasound2t64
60+
61+
- name: Install ffmpeg on macOS
62+
if: runner.os == 'macOS'
63+
run: brew install ffmpeg
64+
65+
- name: Install ffmpeg on Windows
66+
if: runner.os == 'Windows'
67+
shell: powershell
68+
run: choco install ffmpeg -y
69+
70+
- name: Run JavaSE CEF/FFmpeg smoke test
71+
env:
72+
MAVEN_REPO_LOCAL: ${{ github.workspace }}/.m2/repository
73+
run: python scripts/run-javase-cef-ffmpeg-smoke.py
74+
75+
- name: Upload smoke artifacts
76+
if: always()
77+
uses: actions/upload-artifact@v4
78+
with:
79+
name: javase-cef-ffmpeg-smoke-${{ runner.os }}
80+
path: artifacts/javase-cef-ffmpeg-smoke
81+
if-no-files-found: warn

Ports/JavaSE/src/com/codename1/impl/javase/CN1Bootstrap.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,23 @@ public static boolean isCEFLoaded() {
6060
} catch (Throwable ex){}
6161
return false;
6262
}
63+
64+
private static boolean hasFFmpeg() {
65+
File ffmpegDir = getFFmpegDir();
66+
if (ffmpegDir == null || !ffmpegDir.exists()) {
67+
return false;
68+
}
69+
String suffix = isWindows ? ".exe" : "";
70+
return new File(ffmpegDir, "ffmpeg" + suffix).exists() && new File(ffmpegDir, "ffprobe" + suffix).exists();
71+
}
72+
73+
private static File getFFmpegDir() {
74+
String path = System.getProperty("ffmpeg.dir");
75+
if (path == null || path.isEmpty()) {
76+
return null;
77+
}
78+
return new File(path);
79+
}
6380

6481
/**
6582
* Checks to see if this has already bootstrapped the classpath. This doesn't necessarily
@@ -198,6 +215,16 @@ public static boolean run(String mainClass, String[] argv) throws Exception {
198215
System.setProperty("cn1.javase.implementation", "jmf");
199216
}
200217
}
218+
String mediaImplementation = System.getProperty("cn1.javase.mediaImplementation", "");
219+
if ("".equals(mediaImplementation)) {
220+
if (hasFFmpeg()) {
221+
System.setProperty("cn1.javase.mediaImplementation", "ffmpeg");
222+
} else if (fxSupported) {
223+
System.setProperty("cn1.javase.mediaImplementation", "fx");
224+
} else {
225+
System.setProperty("cn1.javase.mediaImplementation", "jmf");
226+
}
227+
}
201228

202229
//loadFXRuntime();
203230
ClassLoader ldr = rootClassLoader == null ?

Ports/JavaSE/src/com/codename1/impl/javase/JavaJMFSEPort.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package com.codename1.impl.javase;
77

88
import com.codename1.io.Log;
9+
import com.codename1.impl.javase.ffmpeg.FFMPEGMedia;
910
import com.codename1.media.AbstractMedia;
1011
import com.codename1.media.AsyncMedia;
1112
import com.codename1.media.Media;
@@ -51,6 +52,9 @@ public class JavaJMFSEPort extends JavaSEPort {
5152

5253
@Override
5354
public AsyncResource<Media> createMediaAsync(final InputStream stream, final String mimeType, final Runnable onCompletion) {
55+
if ("ffmpeg".equalsIgnoreCase(System.getProperty("cn1.javase.mediaImplementation", "")) && FFMPEGMedia.isConfigured()) {
56+
return super.createMediaAsync(stream, mimeType, onCompletion);
57+
}
5458
final AsyncResource<Media> out = new AsyncResource<Media>();
5559
java.awt.Container cnt = canvas.getParent();
5660
while (!(cnt instanceof JFrame)) {
@@ -75,6 +79,9 @@ public void run() {
7579

7680
@Override
7781
public AsyncResource<Media> createMediaAsync(final String uriAddress, final boolean isVideo, final Runnable onCompletion) {
82+
if ("ffmpeg".equalsIgnoreCase(System.getProperty("cn1.javase.mediaImplementation", "")) && FFMPEGMedia.isConfigured()) {
83+
return super.createMediaAsync(uriAddress, isVideo, onCompletion);
84+
}
7885
final AsyncResource<Media> out = new AsyncResource<Media>();
7986
java.awt.Container cnt = canvas.getParent();
8087
while (!(cnt instanceof JFrame)) {

Ports/JavaSE/src/com/codename1/impl/javase/JavaSEPort.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import com.codename1.contacts.Contact;
3333
import com.codename1.db.Database;
3434
import com.codename1.impl.javase.simulator.*;
35+
import com.codename1.impl.javase.ffmpeg.FFMPEGMedia;
3536
import com.codename1.impl.javase.util.MavenUtils;
3637
import com.codename1.impl.javase.util.SwingUtils;
3738
import com.codename1.messaging.Message;
@@ -9583,6 +9584,9 @@ public CN1JPanel() {
95839584

95849585
@Override
95859586
public AsyncResource<Media> createMediaAsync(String uriAddress, final boolean isVideo, final Runnable onCompletion) {
9587+
if ("ffmpeg".equalsIgnoreCase(System.getProperty("cn1.javase.mediaImplementation", "")) && FFMPEGMedia.isConfigured()) {
9588+
return FFMPEGMedia.createMediaAsync(this, uriAddress, isVideo, onCompletion);
9589+
}
95869590
throw new UnsupportedOperationException("Not implemented");
95879591

95889592
}
@@ -9661,6 +9665,9 @@ public Media createMedia(String uriAddress, final boolean isVideo, final Runnabl
96619665
*/
96629666
@Override
96639667
public AsyncResource<Media> createMediaAsync(final InputStream stream, final String mimeType, final Runnable onCompletion) {
9668+
if ("ffmpeg".equalsIgnoreCase(System.getProperty("cn1.javase.mediaImplementation", "")) && FFMPEGMedia.isConfigured()) {
9669+
return FFMPEGMedia.createMediaAsync(this, stream, mimeType, onCompletion);
9670+
}
96649671
throw new UnsupportedOperationException("Not implemented");
96659672

96669673
}
@@ -14439,4 +14446,4 @@ public void nativeBrowserWindowRemoveCloseListener(Object window, com.codename1.
1443914446

1444014447
}
1444114448
// END NATIVE BROWSER WINDOW METHODS---------------------------------------------------------
14442-
}
14449+
}

Ports/JavaSE/src/com/codename1/impl/javase/Simulator.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,16 @@ public class Simulator {
4343

4444
private static final String DEFAULT_SKIN="/iPhoneX.skin";
4545
private static ClassPathLoader rootClassLoader;
46+
47+
private static boolean hasFFmpeg() {
48+
String path = System.getProperty("ffmpeg.dir");
49+
if (path == null || path.isEmpty()) {
50+
return false;
51+
}
52+
File dir = new File(path);
53+
String suffix = isWindows ? ".exe" : "";
54+
return new File(dir, "ffmpeg" + suffix).exists() && new File(dir, "ffprobe" + suffix).exists();
55+
}
4656

4757

4858
/**
@@ -227,6 +237,16 @@ public static void main(final String[] argv) throws Exception {
227237
System.setProperty("cn1.javase.implementation", "jmf");
228238
}
229239
}
240+
String mediaImplementation = System.getProperty("cn1.javase.mediaImplementation", "");
241+
if ("".equals(mediaImplementation)) {
242+
if (hasFFmpeg()) {
243+
System.setProperty("cn1.javase.mediaImplementation", "ffmpeg");
244+
} else if (fxSupported) {
245+
System.setProperty("cn1.javase.mediaImplementation", "fx");
246+
} else {
247+
System.setProperty("cn1.javase.mediaImplementation", "jmf");
248+
}
249+
}
230250

231251
//loadFXRuntime();
232252
ClassLoader ldr = rootClassLoader == null ?
@@ -458,4 +478,4 @@ private List<File> getExtraClasses() {
458478
}
459479
}
460480

461-
}
481+
}

Ports/JavaSE/src/com/codename1/impl/javase/cef/BrowserPanel.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,8 +270,8 @@ public void windowClosing(WindowEvent e) {
270270
// and converting pixels to dips
271271
CN1CefBrowser.setUIPlatform(new CEFUIPlatform());
272272

273-
CefBrowser browser = client_.createBrowser(
274-
startingURL, osrEnabled, transparentPaintingEnabled, null);
273+
CefBrowser browser = new CN1CefBrowser(
274+
client_, startingURL, transparentPaintingEnabled, null);
275275
((CN1CefBrowser)browser).setPeerComponentBuffer(buffer);
276276

277277
setBrowser(browser);

Ports/JavaSE/src/com/codename1/impl/javase/cef/CEFBrowserComponent.java

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@
2323
import javax.swing.JFrame;
2424
import org.cef.CefApp;
2525
import org.cef.CefSettings;
26-
import org.cef.browser.CN1CefBrowserFactory;
27-
import org.cef.browser.CefBrowserFactory;
2826

2927
/**
3028
*
@@ -57,12 +55,6 @@ private static final boolean is64Bit() {
5755
}
5856
return false;
5957
}
60-
static {
61-
62-
CefBrowserFactory.setInstance(new CN1CefBrowserFactory());
63-
64-
}
65-
6658
private static boolean isWindows() {
6759
return (OS.indexOf("win") >= 0);
6860
}

Ports/JavaSE/src/com/codename1/impl/javase/cef/JavaCEFSEPort.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
import com.codename1.impl.javase.AbstractBrowserWindowSE;
2626
import com.codename1.impl.javase.BrowserWindowFactory;
27+
import com.codename1.impl.javase.ffmpeg.FFMPEGMedia;
2728
import com.codename1.impl.javase.fx.FXBrowserWindowSE;
2829
import com.codename1.impl.javase.JavaSEPort;
2930
import static com.codename1.impl.javase.JavaSEPort.checkForPermission;
@@ -592,6 +593,9 @@ public Object getVariable(String key) {
592593

593594
@Override
594595
public AsyncResource<Media> createMediaAsync(InputStream inputStream, String mimeType, Runnable onCompletion) {
596+
if ("ffmpeg".equalsIgnoreCase(System.getProperty("cn1.javase.mediaImplementation", "")) && FFMPEGMedia.isConfigured()) {
597+
return super.createMediaAsync(inputStream, mimeType, onCompletion);
598+
}
595599
final AsyncResource<Media> out = new AsyncResource<Media>();
596600

597601
if(!checkForPermission("android.permission.READ_PHONE_STATE", "This is required to play media")){
@@ -629,6 +633,9 @@ public AsyncResource<Media> createMediaAsync(InputStream inputStream, String mim
629633

630634
@Override
631635
public AsyncResource<Media> createMediaAsync(String uriAddress, boolean isVideo, Runnable onCompletion) {
636+
if ("ffmpeg".equalsIgnoreCase(System.getProperty("cn1.javase.mediaImplementation", "")) && FFMPEGMedia.isConfigured()) {
637+
return super.createMediaAsync(uriAddress, isVideo, onCompletion);
638+
}
632639
final AsyncResource<Media> out = new AsyncResource<Media>();
633640

634641
if(!checkForPermission("android.permission.READ_PHONE_STATE", "This is required to play media")){

Ports/JavaSE/src/com/codename1/impl/javase/cef/RequestHandler.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import org.cef.browser.CefBrowser;
1010
import org.cef.browser.CefFrame;
1111
import org.cef.callback.CefAuthCallback;
12-
import org.cef.callback.CefRequestCallback;
12+
import org.cef.callback.CefCallback;
1313
import org.cef.handler.CefLoadHandler.ErrorCode;
1414
import org.cef.handler.CefRequestHandler;
1515
import org.cef.handler.CefResourceHandler;
@@ -85,6 +85,11 @@ public void run() {
8585
return false;
8686
}
8787

88+
@Override
89+
public boolean onOpenURLFromTab(CefBrowser browser, CefFrame frame, String targetUrl, boolean userGesture) {
90+
return false;
91+
}
92+
8893
@Override
8994
public CefResourceRequestHandler getResourceRequestHandler(CefBrowser browser, CefFrame frame,
9095
CefRequest request, boolean isNavigation, boolean isDownload, String requestInitiator,
@@ -170,13 +175,13 @@ public boolean getAuthCredentials(CefBrowser browser, String origin_url, boolean
170175

171176
@Override
172177
public boolean onQuotaRequest(
173-
CefBrowser browser, String origin_url, long new_size, CefRequestCallback callback) {
178+
CefBrowser browser, String origin_url, long new_size, CefCallback callback) {
174179
return false;
175180
}
176181

177182
@Override
178183
public boolean onCertificateError(CefBrowser browser, ErrorCode cert_error, String request_url,
179-
CefRequestCallback callback) {
184+
CefCallback callback) {
180185
//SwingUtilities.invokeLater(new CertErrorDialog(owner_, cert_error, request_url, callback));
181186
return true;
182187
}

0 commit comments

Comments
 (0)