Skip to content

Commit 867e421

Browse files
authored
Add video player widget
1 parent 67861b3 commit 867e421

File tree

3 files changed

+211
-0
lines changed

3 files changed

+211
-0
lines changed
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
package cloudinary.android.sample;
2+
3+
import android.content.Context;
4+
import android.os.Handler;
5+
import android.os.Looper;
6+
import android.util.Log;
7+
8+
import androidx.test.platform.app.InstrumentationRegistry;
9+
import androidx.test.runner.AndroidJUnit4;
10+
11+
import com.cloudinary.Transformation;
12+
import com.cloudinary.android.cldvideoplayer.CldVideoPlayer;
13+
import com.google.android.exoplayer2.ExoPlayer;
14+
15+
import org.junit.Before;
16+
import org.junit.Test;
17+
import org.junit.runner.RunWith;
18+
19+
import java.net.MalformedURLException;
20+
import java.net.URL;
21+
import java.util.Objects;
22+
import java.util.concurrent.CountDownLatch;
23+
import java.util.concurrent.TimeUnit;
24+
25+
@RunWith(AndroidJUnit4.class)
26+
public class CldVideoPlayerInstrumentedTest {
27+
28+
private Context context;
29+
30+
@Before
31+
public void setUp() {
32+
context = InstrumentationRegistry.getInstrumentation().getTargetContext();
33+
}
34+
35+
@Test
36+
public void testPlayerInitialization() throws InterruptedException {
37+
// Create a CountDownLatch with a count of 1
38+
CountDownLatch latch = new CountDownLatch(1);
39+
final CldVideoPlayer[] cldVideoPlayer = {null};
40+
new Handler(Looper.getMainLooper()).post(() -> {
41+
cldVideoPlayer[0] = new CldVideoPlayer(context, "publicId");
42+
latch.countDown();
43+
});
44+
45+
boolean latchReleased = latch.await(10, TimeUnit.SECONDS);
46+
assert latchReleased : "CountDownLatch was not released within the timeout.";
47+
assert cldVideoPlayer[0] != null;
48+
assert cldVideoPlayer[0].getPlayer() != null;
49+
assert cldVideoPlayer[0].getUrl().contains("publicId.m3u8");
50+
assert cldVideoPlayer[0].getUrl().contains("sp_auto");
51+
}
52+
53+
@Test
54+
public void testDisableStreamProfileAutoWithTransformation() throws InterruptedException {
55+
CountDownLatch latch = new CountDownLatch(1);
56+
final CldVideoPlayer[] cldVideoPlayer = {null};
57+
new Handler(Looper.getMainLooper()).post(() -> {
58+
cldVideoPlayer[0] = new CldVideoPlayer(context, "publicId", new Transformation().effect("sepia"));
59+
latch.countDown();
60+
});
61+
62+
boolean latchReleased = latch.await(10, TimeUnit.SECONDS);
63+
Log.d("Test", cldVideoPlayer[0].getUrl());
64+
assert latchReleased : "CountDownLatch was not released within the timeout.";
65+
assert cldVideoPlayer[0] != null;
66+
assert !cldVideoPlayer[0].getUrl().contains("publicId.m3u8");
67+
assert !cldVideoPlayer[0].getUrl().contains("sp_auto");
68+
}
69+
70+
@Test
71+
public void testInitializePlayerWithURL() throws InterruptedException, MalformedURLException {
72+
URL testUrl = new URL("https://res.cloudinary.com/test/image/upload/sample");
73+
CountDownLatch latch = new CountDownLatch(1);
74+
final CldVideoPlayer[] cldVideoPlayer = {null};
75+
new Handler(Looper.getMainLooper()).post(() -> {
76+
cldVideoPlayer[0] = new CldVideoPlayer(context, testUrl);
77+
latch.countDown();
78+
});
79+
80+
boolean latchReleased = latch.await(10, TimeUnit.SECONDS);
81+
Log.d("Test", cldVideoPlayer[0].getUrl());
82+
assert latchReleased : "CountDownLatch was not released within the timeout.";
83+
assert cldVideoPlayer[0] != null;
84+
assert Objects.equals(cldVideoPlayer[0].getUrl(), testUrl.toString());
85+
}
86+
87+
@Test
88+
public void testInitializePlayerAutoStreamingProfileDisabled() throws InterruptedException {
89+
CountDownLatch latch = new CountDownLatch(1);
90+
final CldVideoPlayer[] cldVideoPlayer = {null};
91+
new Handler(Looper.getMainLooper()).post(() -> {
92+
cldVideoPlayer[0] = new CldVideoPlayer(context, "publicId", null, false);
93+
latch.countDown();
94+
});
95+
96+
boolean latchReleased = latch.await(10, TimeUnit.SECONDS);
97+
Log.d("Test", cldVideoPlayer[0].getUrl());
98+
assert latchReleased : "CountDownLatch was not released within the timeout.";
99+
assert cldVideoPlayer[0] != null;
100+
assert !cldVideoPlayer[0].getUrl().contains("publicId.m3u8");
101+
assert !cldVideoPlayer[0].getUrl().contains("sp_auto");
102+
}
103+
104+
@Test
105+
public void testInitializePlayerAutoStreamingProfileEnabled() throws InterruptedException {
106+
CountDownLatch latch = new CountDownLatch(1);
107+
final CldVideoPlayer[] cldVideoPlayer = {null};
108+
new Handler(Looper.getMainLooper()).post(() -> {
109+
cldVideoPlayer[0] = new CldVideoPlayer(context, "publicId", null, true);
110+
latch.countDown();
111+
});
112+
113+
boolean latchReleased = latch.await(10, TimeUnit.SECONDS);
114+
Log.d("Test", cldVideoPlayer[0].getUrl());
115+
assert latchReleased : "CountDownLatch was not released within the timeout.";
116+
assert cldVideoPlayer[0] != null;
117+
assert cldVideoPlayer[0].getUrl().contains("publicId.m3u8");
118+
assert cldVideoPlayer[0].getUrl().contains("sp_auto");
119+
}
120+
121+
@Test
122+
public void testInitializePlayerAutoStreamingProfileEnabledAndTransformation() throws InterruptedException {
123+
CountDownLatch latch = new CountDownLatch(1);
124+
final CldVideoPlayer[] cldVideoPlayer = {null};
125+
new Handler(Looper.getMainLooper()).post(() -> {
126+
cldVideoPlayer[0] = new CldVideoPlayer(context, "publicId", new Transformation().effect("loop"), true);
127+
latch.countDown();
128+
});
129+
130+
boolean latchReleased = latch.await(10, TimeUnit.SECONDS);
131+
Log.d("Test", cldVideoPlayer[0].getUrl());
132+
assert latchReleased : "CountDownLatch was not released within the timeout.";
133+
assert cldVideoPlayer[0] != null;
134+
assert cldVideoPlayer[0].getUrl().contains("e_loop");
135+
assert !cldVideoPlayer[0].getUrl().contains("publicId.m3u8");
136+
assert !cldVideoPlayer[0].getUrl().contains("sp_auto");
137+
}
138+
}

ui/build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ android {
1313
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
1414
consumerProguardFiles 'consumer-rules.pro'
1515
vectorDrawables.useSupportLibrary = true
16+
multiDexEnabled true
1617
}
1718

1819
buildTypes {
@@ -34,6 +35,8 @@ dependencies {
3435
implementation project(':core')
3536
implementation project(':preprocess')
3637

38+
implementation 'com.google.android.exoplayer:exoplayer:2.16.0'
39+
3740
implementation 'androidx.appcompat:appcompat:1.3.0'
3841
implementation 'com.google.android.material:material:1.4.0'
3942

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package com.cloudinary.android.cldvideoplayer;
2+
3+
import android.content.Context;
4+
import android.util.Log;
5+
6+
import com.cloudinary.Cloudinary;
7+
import com.cloudinary.Transformation;
8+
import com.cloudinary.android.MediaManager;
9+
import com.google.android.exoplayer2.ExoPlayer;
10+
import com.google.android.exoplayer2.MediaItem;
11+
12+
import java.net.URL;
13+
14+
15+
public class CldVideoPlayer {
16+
17+
ExoPlayer player;
18+
19+
String url;
20+
21+
public CldVideoPlayer(Context context, URL url) {
22+
this.url = url.toString();
23+
initPlayer(context, this.url);
24+
}
25+
26+
public CldVideoPlayer(Context context, String publicId) {
27+
initiliaze(context, publicId, null, true);
28+
}
29+
public CldVideoPlayer(Context context, String publicId, Transformation transformation) {
30+
initiliaze(context, publicId, transformation, true);
31+
}
32+
33+
public CldVideoPlayer(Context context, String publicId, Transformation transformation, Boolean automaticStreamingProfile) {
34+
initiliaze(context, publicId, transformation, automaticStreamingProfile);
35+
}
36+
37+
private void initiliaze(Context context, String publicId, Transformation transformation, Boolean automaticStreamingProfile) {
38+
if (automaticStreamingProfile && transformation == null) {
39+
transformation = new Transformation();
40+
transformation.streamingProfile("auto");
41+
this.url = MediaManager.get().url().resourceType("video").transformation(transformation).format("m3u8").generate(publicId);
42+
} else {
43+
this.url = MediaManager.get().url().resourceType("video").transformation(transformation).generate(publicId);
44+
}
45+
46+
initPlayer(context, url);
47+
}
48+
49+
private void initPlayer(Context context, String url) {
50+
player = new ExoPlayer.Builder(context).build();
51+
player.setMediaItem(MediaItem.fromUri(url));
52+
player.prepare();
53+
}
54+
55+
public void play() {
56+
if (player != null) {
57+
player.play();
58+
}
59+
}
60+
61+
public void setPlayer(ExoPlayer player) {
62+
this.player = player;
63+
}
64+
65+
public ExoPlayer getPlayer() {
66+
return player;
67+
}
68+
69+
public String getUrl() { return this.url; }
70+
}

0 commit comments

Comments
 (0)