├── .gitignore
├── .idea
├── compiler.xml
├── deploymentTargetDropDown.xml
├── gradle.xml
├── jarRepositories.xml
├── migrations.xml
├── misc.xml
├── modules.xml
├── modules
│ └── app
│ │ ├── streaming-android.app.androidTest.iml
│ │ ├── streaming-android.app.iml
│ │ ├── streaming-android.app.main.iml
│ │ └── streaming-android.app.unitTest.iml
└── vcs.xml
├── LICENSE
├── README.md
├── TestAndroidProject.iml
├── android-streaming-testbed.iml
├── app
├── .gitignore
├── build.gradle
├── libs
│ └── red5streaming.jar
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── red5pro
│ │ └── org
│ │ └── testandroidproject
│ │ ├── ParamTableActivity.java
│ │ ├── PublishTestListener.java
│ │ ├── TestDetailFragment.java
│ │ ├── TestListActivity.java
│ │ ├── TestListFragment.java
│ │ └── tests
│ │ ├── BandwidthDetectionDownloadOnlyTest
│ │ ├── BandwidthDetectionDownloadOnlyTest.java
│ │ └── README.md
│ │ ├── BandwidthDetectionTest
│ │ ├── BandwidthDetectionTest.java
│ │ └── README.md
│ │ ├── BandwidthDetectionUploadOnlyTest
│ │ ├── BandwidthDetectionUploadOnlyTest.java
│ │ └── README.md
│ │ ├── ConferenceStreamManagerTest
│ │ ├── ConferenceStreamManagerTest.java
│ │ └── README.md
│ │ ├── ConferenceTest
│ │ ├── ConferenceTest.java
│ │ ├── README.md
│ │ └── WebSocketProvider.java
│ │ ├── Home
│ │ └── Home.java
│ │ ├── ParamTable
│ │ └── ParamTable.java
│ │ ├── PublishABRTest
│ │ ├── PublishABRTest.java
│ │ └── README.md
│ │ ├── PublishAspectTest
│ │ ├── PublishAspectTest.java
│ │ └── README.md
│ │ ├── PublishAuthTest
│ │ ├── PublishAuthTest.java
│ │ └── README.md
│ │ ├── PublishBackgroundTest
│ │ ├── PublishBackgroundTest.java
│ │ ├── PublishService.java
│ │ └── README.md
│ │ ├── PublishCamera2Test
│ │ ├── PublishCamera2Test.java
│ │ └── README.md
│ │ ├── PublishCameraDeviceOrientationTest
│ │ ├── PublishCameraDeviceOrientationTest.java
│ │ └── README.md
│ │ ├── PublishCameraSwapBlinkTest
│ │ ├── PublishCameraSwapBlinkTest.java
│ │ └── README.md
│ │ ├── PublishCameraSwapTest
│ │ ├── PublishCameraSwapTest.java
│ │ └── README.md
│ │ ├── PublishCustomMicTest
│ │ ├── PublishCustomMicTest.java
│ │ └── Readme.md
│ │ ├── PublishCustomSourceTest
│ │ ├── CustomVideoSource.java
│ │ ├── PublishCustomSourceTest.java
│ │ └── Readme.md
│ │ ├── PublishDeviceOrientationTest
│ │ ├── PublishDeviceOrientationTest.java
│ │ └── README.md
│ │ ├── PublishEncryptedTest
│ │ ├── PublishEncryptedTest.java
│ │ └── README.md
│ │ ├── PublishHQAudioTest
│ │ ├── PublishHQAudioTest.java
│ │ └── README.md
│ │ ├── PublishImageTest
│ │ ├── PublishImageTest.java
│ │ └── README.md
│ │ ├── PublishLocalRecordTest
│ │ ├── PublishLocalRecordTest.java
│ │ └── README.md
│ │ ├── PublishOrientationTest
│ │ ├── PublishOrientationTest.java
│ │ └── README.md
│ │ ├── PublishPauseTest
│ │ ├── PublishPauseTest.java
│ │ └── README.md
│ │ ├── PublishRemoteCallTest
│ │ ├── PublishRemoteCallTest.java
│ │ └── README.md
│ │ ├── PublishSMEncryptedTest
│ │ ├── PublishSMEncryptedTest.java
│ │ └── README.md
│ │ ├── PublishSMEncryptedTest_SM1
│ │ ├── PublishSMEncryptedTest_SM1.java
│ │ └── README.md
│ │ ├── PublishStreamManagerTest
│ │ ├── PublishStreamManagerTest.java
│ │ └── README.md
│ │ ├── PublishStreamManagerTest_SM1
│ │ ├── PublishStreamManagerTest_SM1.java
│ │ └── README.md
│ │ ├── PublishStreamManagerTranscodeTest
│ │ ├── PublishStreamManagerTranscodeTest.java
│ │ ├── PublishTranscoderData.java
│ │ ├── PublishTranscoderForm.java
│ │ └── README.md
│ │ ├── PublishStreamManagerTranscodeTest_SM1
│ │ ├── PublishStreamManagerTranscodeTest_SM1.java
│ │ ├── PublishTranscoderData_SM1.java
│ │ ├── PublishTranscoderForm_SM1.java
│ │ └── README.md
│ │ ├── PublishTest
│ │ ├── PublishTest.java
│ │ └── README.md
│ │ ├── RecordedTest
│ │ ├── Readme.md
│ │ └── RecordedTest.java
│ │ ├── SharedObjectStreamlessTest
│ │ ├── README.md
│ │ └── SharedObjectStreamlessTest.java
│ │ ├── SharedObjectTest
│ │ ├── README.md
│ │ └── SharedObjectTest.java
│ │ ├── Subscribe360Test
│ │ ├── CustomVideoViewRenderer.java
│ │ └── Subscribe360Test.java
│ │ ├── SubscribeAspectTest
│ │ ├── README.md
│ │ └── SubscribeAspectTest.java
│ │ ├── SubscribeAuthTest
│ │ ├── README.md
│ │ └── SubscribeAuthTest.java
│ │ ├── SubscribeBackgroundTest
│ │ ├── README.md
│ │ ├── SubscribeBackgroundTest.java
│ │ └── SubscribeService.java
│ │ ├── SubscribeBandwidthTest
│ │ ├── README.md
│ │ └── SubscribeBandwidthTest.java
│ │ ├── SubscribeCluster
│ │ ├── README.md
│ │ └── SubscribeCluster.java
│ │ ├── SubscribeEncryptedTest
│ │ ├── README.md
│ │ └── SubscribeEncryptedTest.java
│ │ ├── SubscribeHardwareAccelerationTest
│ │ ├── README.md
│ │ └── SubscribeHardwareAccelerationTest.java
│ │ ├── SubscribeImageTest
│ │ ├── README.md
│ │ └── SubscribeImageTest.java
│ │ ├── SubscribeMuteTest
│ │ ├── README.md
│ │ └── SubscribeMuteTest.java
│ │ ├── SubscribeNoViewTest
│ │ ├── README.md
│ │ └── SubscribeNoViewTest.java
│ │ ├── SubscribeReconnectTest
│ │ ├── README.md
│ │ └── SubscribeReconnectTest.java
│ │ ├── SubscribeRemoteCallTest
│ │ ├── README.md
│ │ └── SubscribeRemoteCallTest.java
│ │ ├── SubscribeRendererRGBScalarTest
│ │ ├── README.md
│ │ └── SubscribeRendererRGBScalarTest.java
│ │ ├── SubscribeSMEncryptedTest
│ │ ├── README.md
│ │ └── SubscribeSMEncryptedTest.java
│ │ ├── SubscribeSMEncryptedTest_SM1
│ │ ├── README.md
│ │ └── SubscribeSMEncryptedTest_SM1.java
│ │ ├── SubscribeSetVolumeTest
│ │ ├── README.md
│ │ └── SubscribeSetVolumeTest.java
│ │ ├── SubscribeStreamManagerTest
│ │ ├── README.md
│ │ └── SubscribeStreamManagerTest.java
│ │ ├── SubscribeStreamManagerTest_SM1
│ │ ├── README.md
│ │ └── SubscribeStreamManagerTest_SM1.java
│ │ ├── SubscribeStreamManagerTranscoderTest
│ │ ├── README.md
│ │ └── SubscribeStreamManagerTranscoderTest.java
│ │ ├── SubscribeStreamManagerTranscoderTest_SM1
│ │ ├── README.md
│ │ └── SubscribeStreamManagerTranscoderTest_SM1.java
│ │ ├── SubscribeTest
│ │ ├── README.md
│ │ └── SubscribeTest.java
│ │ ├── SubscribeTwoStreamTest
│ │ ├── Readme.md
│ │ └── SubscribeTwoStreamTest.java
│ │ └── TestContent.java
│ ├── jniLibs
│ ├── arm64-v8a
│ │ ├── libred5android.so
│ │ └── libred5streaming.so
│ ├── armeabi-v7a
│ │ ├── libred5android.so
│ │ └── libred5streaming.so
│ └── x86
│ │ ├── libred5android.so
│ │ └── libred5streaming.so
│ └── res
│ ├── drawable-hdpi
│ └── ic_launcher.png
│ ├── drawable-mdpi
│ └── ic_launcher.png
│ ├── drawable-xhdpi
│ └── ic_launcher.png
│ ├── drawable-xxhdpi
│ └── ic_launcher.png
│ ├── drawable
│ └── ic_launcher.png
│ ├── layout-sw600dp
│ └── activity_test_list.xml
│ ├── layout
│ ├── activity_param_table.xml
│ ├── activity_test_list.xml
│ ├── bg_publish_test.xml
│ ├── bg_subscribe_test.xml
│ ├── conference_test.xml
│ ├── double_view.xml
│ ├── fragment_param_table.xml
│ ├── fragment_test_detail.xml
│ ├── home_screen.xml
│ ├── param_table_row_editable.xml
│ ├── publish_sm_transcoder_test.xml
│ ├── publish_test.xml
│ ├── shared_object_streamless_test.xml
│ ├── shared_object_test.xml
│ ├── subscribe_mute_test.xml
│ ├── subscribe_scrub_test.xml
│ ├── subscribe_sm_transcoder_test.xml
│ ├── subscribe_test.xml
│ └── twoway_test.xml
│ ├── raw
│ └── tests.xml
│ ├── values-w820dp
│ └── dimens.xml
│ └── values
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
├── build.gradle
├── git-hooks
├── README.md
└── pre-commit
├── gradle.properties
├── gradle
└── wrapper
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── scripts
├── LICENSE_INJECT
└── license_inject.sh
├── settings.gradle
└── streaming-android.iml
/.gitignore:
--------------------------------------------------------------------------------
1 | *.class
2 |
3 | # Mobile Tools for Java (J2ME)
4 | .mtj.tmp/
5 |
6 | # Package Files #
7 | *.jar
8 | *.war
9 | *.ear
10 |
11 | # Explicitly allow the following files #
12 | !red5streaming.jar
13 |
14 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
15 | hs_err_pid*
16 |
17 | .gradle
18 | /local.properties
19 | /.idea/workspace.xml
20 | /.idea/libraries
21 | .DS_Store
22 | /build
23 | /.idea/caches
24 | /.idea/codeStyles
25 | /.idea/copilot
26 | /.idea/deploymentTargetDropDown.xml
27 | /.idea/migrations.xml
28 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/deploymentTargetDropDown.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
18 |
19 |
--------------------------------------------------------------------------------
/.idea/jarRepositories.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/.idea/migrations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/modules/app/streaming-android.app.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright © 2015 Infrared5, Inc. All rights reserved.
2 |
3 | The accompanying code comprising examples for use solely in conjunction with Red5 Pro (the "Example Code")
4 | is licensed to you by Infrared5 Inc. in consideration of your agreement to the following
5 | license terms and conditions. Access, use, modification, or redistribution of the accompanying
6 | code constitutes your acceptance of the following license terms and conditions.
7 |
8 | Permission is hereby granted, free of charge, to you to use the Example Code and associated documentation
9 | files (collectively, the "Software") without restriction, including without limitation the rights to use,
10 | copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
11 | persons to whom the Software is furnished to do so, subject to the following conditions:
12 |
13 | The Software shall be used solely in conjunction with Red5 Pro. Red5 Pro is licensed under a separate end
14 | user license agreement (the "EULA"), which must be executed with Infrared5, Inc.
15 | An example of the EULA can be found on our website at: https://account.red5pro.com/assets/LICENSE.txt.
16 |
17 | The above copyright notice and this license shall be included in all copies or portions of the Software.
18 |
19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
20 | NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 | NONINFRINGEMENT. IN NO EVENT SHALL INFRARED5, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 |
--------------------------------------------------------------------------------
/TestAndroidProject.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/android-streaming-testbed.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | android {
3 | compileSdkVersion 30
4 | buildToolsVersion '19.1.0'
5 | defaultConfig {
6 | applicationId "red5pro.org.testandroidproject"
7 | minSdkVersion 26
8 | targetSdkVersion 30
9 | versionCode 9000
10 | versionName "10.9.0.0"
11 | }
12 | buildTypes {
13 | release {
14 | minifyEnabled false
15 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
16 | }
17 | }
18 | lintOptions {
19 | checkReleaseBuilds false
20 | // Or, if you prefer, you can continue to check for errors in release builds,
21 | // but continue the build even when errors are found:
22 | abortOnError false
23 | }
24 | // productFlavors {
25 | //
26 | // armv7 {
27 | // ndk {
28 | // abiFilters "armeabi-v7a"
29 | // }
30 | // }
31 | //
32 | //// x86{
33 | //// ndk{
34 | //// abiFilters "x86"
35 | //// }
36 | //// }
37 | //
38 | // }
39 | buildToolsVersion '28.0.3'
40 | useLibrary 'org.apache.http.legacy'
41 | }
42 | dependencies {
43 | implementation fileTree(include: ['*.jar'], dir: 'libs')
44 | implementation 'org.java-websocket:Java-WebSocket:1.5.2'
45 | implementation 'ch.qos.logback:logback-classic:1.2.3'
46 | implementation 'ch.qos.logback:logback-core:1.2.3'
47 | implementation 'org.apache.mina:mina-core:2.1.3'
48 | implementation 'org.slf4j:slf4j-api:1.7.28'
49 | implementation 'com.googlecode.mp4parser:isoparser:1.1.22'
50 | implementation 'com.google.code.gson:gson:2.8.6'
51 | implementation 'androidx.legacy:legacy-support-core-ui:1.0.0'
52 | }
53 |
--------------------------------------------------------------------------------
/app/libs/red5streaming.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/red5pro/streaming-android/2c8796a5f87512a0c23983945e7724da386d436a/app/libs/red5streaming.jar
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Applications/Android Studio.app/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
19 | #-keep class com.red5pro.streaming.** { *; }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
18 |
21 |
22 |
27 |
28 |
31 |
32 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
49 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/app/src/main/java/red5pro/org/testandroidproject/ParamTableActivity.java:
--------------------------------------------------------------------------------
1 | package red5pro.org.testandroidproject;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.view.WindowManager;
6 |
7 | public class ParamTableActivity extends Activity {
8 | @Override
9 | protected void onCreate(Bundle savedInstanceState) {
10 | super.onCreate(savedInstanceState);
11 | setContentView(R.layout.activity_param_table);
12 |
13 | getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
14 |
15 | // Show the Up button in the action bar.
16 | getActionBar().setDisplayHomeAsUpEnabled(true);
17 |
18 | // savedInstanceState is non-null when there is fragment state
19 | // saved from previous configurations of this activity
20 | // (e.g. when rotating the screen from portrait to landscape).
21 | // In this case, the fragment will automatically be re-added
22 | // to its container so we don't need to manually add it.
23 | // For more information, see the Fragments API guide at:
24 | //
25 | // http://developer.android.com/guide/components/fragments.html
26 | //
27 | if (savedInstanceState == null) {
28 | // Create the detail fragment and add it to the activity
29 | // using a fragment transaction.
30 | // Bundle arguments = new Bundle();
31 | // arguments.putString(TestDetailFragment.ARG_ITEM_ID,
32 | // getIntent().getStringExtra(TestDetailFragment.ARG_ITEM_ID));
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/main/java/red5pro/org/testandroidproject/PublishTestListener.java:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright © 2015 Infrared5, Inc. All rights reserved.
3 | //
4 | // The accompanying code comprising examples for use solely in conjunction with Red5 Pro (the "Example Code")
5 | // is licensed to you by Infrared5 Inc. in consideration of your agreement to the following
6 | // license terms and conditions. Access, use, modification, or redistribution of the accompanying
7 | // code constitutes your acceptance of the following license terms and conditions.
8 | //
9 | // Permission is hereby granted, free of charge, to you to use the Example Code and associated documentation
10 | // files (collectively, the "Software") without restriction, including without limitation the rights to use,
11 | // copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
12 | // persons to whom the Software is furnished to do so, subject to the following conditions:
13 | //
14 | // The Software shall be used solely in conjunction with Red5 Pro. Red5 Pro is licensed under a separate end
15 | // user license agreement (the "EULA"), which must be executed with Infrared5, Inc.
16 | // An example of the EULA can be found on our website at: https://account.red5pro.com/assets/LICENSE.txt.
17 | //
18 | // The above copyright notice and this license shall be included in all copies or portions of the Software.
19 | //
20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
21 | // NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 | // NONINFRINGEMENT. IN NO EVENT SHALL INFRARED5, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 | //
26 | package red5pro.org.testandroidproject;
27 |
28 | /**
29 | * Created by toddanderson on 8/10/17.
30 | */
31 |
32 | public interface PublishTestListener {
33 | void onPublishFlushBufferStart();
34 | void onPublishFlushBufferComplete();
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/main/java/red5pro/org/testandroidproject/tests/BandwidthDetectionDownloadOnlyTest/README.md:
--------------------------------------------------------------------------------
1 | # Bandwidth Detection (Download) with Red5 Pro
2 |
3 | This example shows how to easily detect download bandwidth with Red5 Pro prior to subscribing to a stream.
4 |
5 | ## Example Code
6 |
7 | * **_[TestDetailFragment.java](../../TestDetailFragment.java)_**
8 | * **_[BandwidthDetectionDownloadOnlyTest.java](BandwidthDetectionDownloadOnlyTest.java)_**
9 |
10 | ## How to Check Bandwidth
11 |
12 | Checking the download bandwidth prior to subscribing to a stream is relatively simple, requiring only a few pieces of setup.
13 |
14 | 1. One must [instantiate an `R5BandwidthDetection` instance](BandwidthDetectionDownloadOnlyTest.java#L75)
15 | 2. One must then [utilize the `checkDownloadSpeed` method](BandwidthDetectionDownloadOnlyTest.java#L77) of that instance
16 | 3. Doing so requires passing in:
17 | 1. The base url (usually the same as the `host` you would provide to your `R5Configuration`)
18 | 2. How long you wish the total bandwidth test to take, in seconds
19 | 3. Callback blocks for the successful and unsuccessful attempts at checking the bandwidth
20 |
21 | A simplified example of this would be:
22 |
23 | ```java
24 | R5BandwidthDetection detection = new R5BandwidthDetection(this); // Or your listener that implements R5BandwidthDetection.CallbackListener
25 | try {
26 | detection.checkDownloadSpeed("your-host-here", 2.5);
27 | } catch (Exception e) {
28 | e.printStackTrace();
29 | }
30 | ```
31 |
32 | The rest of this example is based on [SubscribeTest.java](../SubscribeTest/) and ensures that a [minimum bandwidth](BandwidthDetectionDownloadOnlyTest.java#L153) (as [defined by the `tests.xml` file](../../../../../../res/raw/tests.xml#L3)) is met prior to subscribing to the stream.
33 |
--------------------------------------------------------------------------------
/app/src/main/java/red5pro/org/testandroidproject/tests/BandwidthDetectionTest/README.md:
--------------------------------------------------------------------------------
1 | # Bandwidth Detection with Red5 Pro
2 |
3 | This example shows how to easily detect upload and download bandwidth with Red5 Pro prior to beginning a stream.
4 |
5 | ## Example Code
6 |
7 | * **_[TestDetailFragment.java](../../TestDetailFragment.java)_**
8 | * **_[BandwidthDetectionTest.java](BandwidthDetectionTest.java)_**
9 |
10 | ## How to Check Bandwidth
11 |
12 | Checking the bandwidth (download and upload simultaneously) prior to beginning a stream is relatively simple, requiring only a few pieces of setup.
13 |
14 | 1. One must [instantiate an `R5BandwidthDetection` instance](BandwidthDetectionTest.java#L75)
15 | 2. One must then [utilize the `checkSpeeds` method](BandwidthDetectionTest.java#L77) of that instance
16 | 3. Doing so requires passing in:
17 | 1. The base url (usually the same as the `host` you would provide to your `R5Configuration`)
18 | 2. How long you wish the total bandwidth test to take, in seconds
19 | 3. Callback blocks for the successful and unsuccessful attempts at checking the bandwidth
20 |
21 | A simplified example of this would be:
22 |
23 | ```java
24 | R5BandwidthDetection detection = new R5BandwidthDetection(this); // Or your listener that implements R5BandwidthDetection.CallbackListener
25 | try {
26 | detection.checkSpeeds("your-host-here", 2.5);
27 | } catch (Exception e) {
28 | e.printStackTrace();
29 | }
30 | ```
31 |
32 | The rest of this example is based on [SubscribeTest.java](../SubscribeTest/) and ensures that a [minimum bandwidth](BandwidthDetectionTest.java#L158) (as [defined by the `tests.xml` file](../../../../../../res/raw/tests.xml#L3)) is met prior to subscribing to the stream.
33 |
--------------------------------------------------------------------------------
/app/src/main/java/red5pro/org/testandroidproject/tests/BandwidthDetectionUploadOnlyTest/README.md:
--------------------------------------------------------------------------------
1 | # Bandwidth Detection (Upload) with Red5 Pro
2 |
3 | This example shows how to easily detect upload bandwidth with Red5 Pro prior to publishing a stream.
4 |
5 | ## Example Code
6 |
7 | * **_[TestDetailFragment.java](../../TestDetailFragment.java)_**
8 | * **_[BandwidthDetectionUploadOnlyTest.java](BandwidthDetectionUploadOnlyTest.java)_**
9 |
10 | ## How to Check Bandwidth
11 |
12 | Checking the upload bandwidth prior to publishing a stream is relatively simple, requiring only a few pieces of setup.
13 |
14 | 1. One must [instantiate an `R5BandwidthDetection` instance](BandwidthDetectionUploadOnlyTest.java#L92)
15 | 2. One must then [utilize the `checkUploadSpeed` method](BandwidthDetectionUploadOnlyTest.java#L94) of that instance
16 | 3. Doing so requires passing in:
17 | 1. The base url (usually the same as the `host` you would provide to your `R5Configuration`)
18 | 2. How long you wish the total bandwidth test to take, in seconds
19 | 3. Callback blocks for the successful and unsuccessful attempts at checking the bandwidth
20 |
21 | A simplified example of this would be:
22 |
23 | ```java
24 | R5BandwidthDetection detection = new R5BandwidthDetection(this); // Or your listener that implements R5BandwidthDetection.CallbackListener
25 | try {
26 | detection.checkUploadSpeed("your-host-here", 2.5);
27 | } catch (Exception e) {
28 | e.printStackTrace();
29 | }
30 | ```
31 |
32 | The rest of this example is based on [PublishTest.java](../PublishTest/) and ensures that a [minimum bandwidth](BandwidthDetectionUploadOnlyTest.java#L214) (as [defined by the `tests.xml` file](../../../../../../res/raw/tests.xml#L3)) is met prior to publishing to the stream.
33 |
--------------------------------------------------------------------------------
/app/src/main/java/red5pro/org/testandroidproject/tests/ConferenceStreamManagerTest/README.md:
--------------------------------------------------------------------------------
1 | # Conference Chat
2 |
3 | This example demonstrates multi-party communication using Red5 Pro. It should be used in conjunction with a conference WebSocket host such as [this example](https://github.com/red5pro/red5pro-conference-host).
4 |
5 | It is recommended to view this example as part of the `webrtcexamples` webapp shipped with the [Red5 Pro Server](https://account.red5pro.com/download).
6 |
7 | ## Basic Publisher
8 |
9 | **Please refer to the [Basic Publisher Documentation](../PublishTest/README.md) to learn more about the basic setup of a publisher.**
10 |
11 | ## Basic Subscriber
12 |
13 | **Please refer to the [Basic Subscriber Documentation](../SubscribeTest/README.md) to learn more about the basic setup of a subscriber.**
14 |
15 | ## Example Code
16 |
17 | - **[ConferenceTest.java](ConferenceTest.java)**
18 | - **[WebSocketProvider.java](WebSocketProvider.java)**
19 |
20 | # Setup
21 |
22 | ## WebSocket Conference Host
23 |
24 | The `WebSocket Conference Host` refers to the socket endpoint that manages the list of active streams and their scopes for a given conference session.
25 |
26 | We have provided a basic example at [https://github.com/red5pro/red5pro-conference-host](https://github.com/red5pro/red5pro-conference-host).
27 |
28 | The endpoint for the `WebSocket Conference Host` is defined in the **tests.xml** as the `conference_host` property. By default it is set to a local IP address and port on your network (e.g., `ws://10.0.0.75:8001`). Change this to either the local IP or the remote IP of the machine that you launch the `WebSocket Conference Host` on.
29 |
30 | > The reason it is defined as a local IP on your network and not `localhost` is because `localhost` would refer to the actual device that the testbed is launched on. We assume you would not also be running the `WebSocket Conference Host` NodeJS server on your iOS device :)
31 |
32 | Once a publish session has begun, a connection to the `WebSocket Conference Host` is established and messages with regards to active stream listing are handled:
33 |
34 | ```java
35 | public void connectSocket () {
36 | final String sRoomName = this.roomName;
37 | String host = TestContent.GetPropertyString("conference_host")
38 | .replace("http:", "ws:")
39 | .replace("https:", "wss:");
40 | String url = host + "?room=" + sRoomName + "&streamName=" + this.pubName;
41 | mWebSocketProvider = new WebSocketProvider(url);
42 | mWebSocketProvider.connect(new WebSocketProvider.OnWebSocketListener() {
43 | @Override
44 | public void onWebSocketMessage(String room, ArrayList streams) {
45 | if (room.equals(sRoomName)) {
46 | String streamNames = TextUtils.join(",", streams);
47 | stringToQueue(streamNames);
48 | }
49 | }
50 | });
51 | }
52 | ```
53 |
54 | ## Java-WebSocket
55 |
56 | By default, the WebSocket implementation used is the [Java-WebSocket](https://github.com/TooTallNate/Java-WebSocket) Java library. It is installed via `gradle`.
57 |
58 |
--------------------------------------------------------------------------------
/app/src/main/java/red5pro/org/testandroidproject/tests/ConferenceTest/README.md:
--------------------------------------------------------------------------------
1 | # Conference Chat
2 |
3 | This example demonstrates multi-party communication using Red5 Pro. It should be used in conjunction with a conference WebSocket host such as [this example](https://github.com/red5pro/red5pro-conference-host).
4 |
5 | It is recommended to view this example as part of the `webrtcexamples` webapp shipped with the [Red5 Pro Server](https://account.red5pro.com/download).
6 |
7 | ## Basic Publisher
8 |
9 | **Please refer to the [Basic Publisher Documentation](../PublishTest/README.md) to learn more about the basic setup of a publisher.**
10 |
11 | ## Basic Subscriber
12 |
13 | **Please refer to the [Basic Subscriber Documentation](../SubscribeTest/README.md) to learn more about the basic setup of a subscriber.**
14 |
15 | ## Example Code
16 |
17 | - **[ConferenceTest.java](ConferenceTest.java)**
18 | - **[WebSocketProvider.java](WebSocketProvider.java)**
19 |
20 | # Setup
21 |
22 | ## WebSocket Conference Host
23 |
24 | The `WebSocket Conference Host` refers to the socket endpoint that manages the list of active streams and their scopes for a given conference session.
25 |
26 | We have provided a basic example at [https://github.com/red5pro/red5pro-conference-host](https://github.com/red5pro/red5pro-conference-host).
27 |
28 | The endpoint for the `WebSocket Conference Host` is defined in the **tests.xml** as the `conference_host` property. By default it is set to a local IP address and port on your network (e.g., `ws://10.0.0.75:8001`). Change this to either the local IP or the remote IP of the machine that you launch the `WebSocket Conference Host` on.
29 |
30 | > The reason it is defined as a local IP on your network and not `localhost` is because `localhost` would refer to the actual device that the testbed is launched on. We assume you would not also be running the `WebSocket Conference Host` NodeJS server on your iOS device :)
31 |
32 | Once a publish session has begun, a connection to the `WebSocket Conference Host` is established and messages with regards to active stream listing are handled:
33 |
34 | ```java
35 | public void connectSocket () {
36 | final String sRoomName = this.roomName;
37 | String host = TestContent.GetPropertyString("conference_host")
38 | .replace("http:", "ws:")
39 | .replace("https:", "wss:");
40 | String url = host + "?room=" + sRoomName + "&streamName=" + this.pubName;
41 | mWebSocketProvider = new WebSocketProvider(url);
42 | mWebSocketProvider.connect(new WebSocketProvider.OnWebSocketListener() {
43 | @Override
44 | public void onWebSocketMessage(String room, ArrayList streams) {
45 | if (room.equals(sRoomName)) {
46 | String streamNames = TextUtils.join(",", streams);
47 | stringToQueue(streamNames);
48 | }
49 | }
50 | });
51 | }
52 | ```
53 |
54 | ## Java-WebSocket
55 |
56 | By default, the WebSocket implementation used is the [Java-WebSocket](https://github.com/TooTallNate/Java-WebSocket) Java library. It is installed via `gradle`.
57 |
58 |
--------------------------------------------------------------------------------
/app/src/main/java/red5pro/org/testandroidproject/tests/ConferenceTest/WebSocketProvider.java:
--------------------------------------------------------------------------------
1 | package red5pro.org.testandroidproject.tests.ConferenceTest;
2 |
3 | import android.util.Log;
4 |
5 | import org.java_websocket.client.WebSocketClient;
6 | import org.java_websocket.handshake.ServerHandshake;
7 | import org.json.JSONArray;
8 | import org.json.JSONObject;
9 |
10 | import java.net.URI;
11 | import java.net.URISyntaxException;
12 | import java.util.ArrayList;
13 |
14 | public class WebSocketProvider {
15 |
16 | private String url;
17 | private WebSocketClient mWebSocketClient;
18 |
19 | interface OnWebSocketListener {
20 | void onWebSocketMessage(String room, ArrayList streams);
21 | }
22 |
23 | public WebSocketProvider (String url) {
24 | this.url = url;
25 | }
26 |
27 | private URI generateURI (String url) {
28 | try {
29 | return new URI(url);
30 | } catch (URISyntaxException e) {
31 | e.printStackTrace();
32 | return null;
33 | }
34 | }
35 |
36 | public void connect (final WebSocketProvider.OnWebSocketListener callback) {
37 | URI uri = generateURI(url);
38 | if (uri == null) return;
39 |
40 | mWebSocketClient = new WebSocketClient(uri) {
41 |
42 | @Override
43 | public void onOpen(ServerHandshake handshakedata) {}
44 |
45 | @Override
46 | public void onMessage(String message) {
47 | Log.d("MESSAGE", message);
48 | try {
49 | JSONObject payload = new JSONObject(message);
50 | String room = payload.getString("room");
51 | JSONArray streams = payload.getJSONArray("streams");
52 | ArrayList streamNames = new ArrayList();
53 | if (streams != null) {
54 | for (int i=0; i params) {
68 | Iterator iterator = params.entrySet().iterator();
69 | while (iterator.hasNext()) {
70 | Map.Entry mapElement = (Map.Entry)iterator.next();
71 | addFilledEntry((String)mapElement.getKey(), (String)mapElement.getValue());
72 | }
73 | }
74 |
75 | private void addFilledEntry (String name, String value) {
76 | final View row = inflater.inflate(R.layout.param_table_row_editable, null,false);
77 | EditText nameField = (EditText) row.findViewById(R.id.name_field);
78 | EditText valueField = (EditText) row.findViewById(R.id.value_field);
79 | Button removeButton = (Button) row.findViewById(R.id.remove_button);
80 | removeButton.setOnClickListener(new View.OnClickListener() {
81 | @Override
82 | public void onClick(View v) {
83 | table.removeView(row);
84 | }
85 | });
86 | nameField.setText(name);
87 | valueField.setText(value);
88 | table.addView(row);
89 | }
90 |
91 | private void addEmptyEntry () {
92 | final View row = inflater.inflate(R.layout.param_table_row_editable, null,false);
93 | Button removeButton = (Button) row.findViewById(R.id.remove_button);
94 | removeButton.setOnClickListener(new View.OnClickListener() {
95 | @Override
96 | public void onClick(View v) {
97 | table.removeView(row);
98 | }
99 | });
100 | table.addView(row);
101 | }
102 |
103 | private boolean onAddTouch(MotionEvent e ) {
104 | if( e.getAction() == MotionEvent.ACTION_DOWN ) {
105 | addEmptyEntry();
106 | }
107 | return true;
108 | }
109 |
110 | @Override
111 | public void onDestroy () {
112 | serializeConnectionParams(table);
113 | super.onDestroy();
114 | }
115 |
116 | }
117 |
--------------------------------------------------------------------------------
/app/src/main/java/red5pro/org/testandroidproject/tests/PublishABRTest/README.md:
--------------------------------------------------------------------------------
1 | # Adaptive Bitrate Publishing
2 |
3 | This example demonstrates the AdaptiveBitrateController, which provides a mechanism to dynamically adjust the video publishing bitrate to adjust quality to meet the bandwidth restrictions of the network connection or encoding hardware.
4 |
5 | ### Example Code
6 |
7 | - ***[PublishTest.java](../PublishTest/PublishTest.java)***
8 | - ***[PublishABRTest.java](PublishABRTest.java)***
9 |
10 | ### Setup
11 |
12 | The AdaptiveBitrateController is simple to setup. You simply create a new instance of the controller and attach the stream you wish to control. It will monitor the stream and make all adjustments automatically for you.
13 |
14 | ```Java
15 | R5AdaptiveBitrateController adaptor = new R5AdaptiveBitrateController();
16 | adaptor.AttachStream(publish);
17 | ```
18 |
19 | [PublishABRTest.java #56](PublishABRTest.java#L56)
20 |
21 | The controller will continuously adjust the video bitrate until the stream has closed.
22 |
23 | ### Range
24 |
25 | The AdaptiveBitrateController will dynamically adjust the video bitrate between the lowest possible bitrate the encoder can encode at, and the value set on the R5VideoSource (typically an R5Camera) on the stream. In this case, the value is assigned according to the value in tests.xml
26 |
27 | ```Java
28 | camera.setBitrate(TestContent.GetPropertyInt("bitrate"));
29 | ```
30 |
31 | [PublishABRTest.java #53](PublishABRTest.java#L53)
32 |
33 | The controller will adjust the bitrate ~200 kbps every 2 seconds to achieve the best possible video quality.
34 |
35 | Video will be turned off if the stream is unable to maintain a smooth connection at the lowest possible bitrate. You can force video to be included with the `AdaptiveBitrateController.requiresVideo` flag.
--------------------------------------------------------------------------------
/app/src/main/java/red5pro/org/testandroidproject/tests/PublishAspectTest/PublishAspectTest.java:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright © 2015 Infrared5, Inc. All rights reserved.
3 | //
4 | // The accompanying code comprising examples for use solely in conjunction with Red5 Pro (the "Example Code")
5 | // is licensed to you by Infrared5 Inc. in consideration of your agreement to the following
6 | // license terms and conditions. Access, use, modification, or redistribution of the accompanying
7 | // code constitutes your acceptance of the following license terms and conditions.
8 | //
9 | // Permission is hereby granted, free of charge, to you to use the Example Code and associated documentation
10 | // files (collectively, the "Software") without restriction, including without limitation the rights to use,
11 | // copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
12 | // persons to whom the Software is furnished to do so, subject to the following conditions:
13 | //
14 | // The Software shall be used solely in conjunction with Red5 Pro. Red5 Pro is licensed under a separate end
15 | // user license agreement (the "EULA"), which must be executed with Infrared5, Inc.
16 | // An example of the EULA can be found on our website at: https://account.red5pro.com/assets/LICENSE.txt.
17 | //
18 | // The above copyright notice and this license shall be included in all copies or portions of the Software.
19 | //
20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
21 | // NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 | // NONINFRINGEMENT. IN NO EVENT SHALL INFRARED5, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 | //
26 | package red5pro.org.testandroidproject.tests.PublishAspectTest;
27 |
28 | import android.os.Bundle;
29 | import android.view.MotionEvent;
30 | import android.view.View;
31 |
32 | import red5pro.org.testandroidproject.tests.PublishTest.PublishTest;
33 |
34 | /**
35 | * Created by davidHeimann on 11/20/17.
36 | */
37 |
38 | public class PublishAspectTest extends PublishTest {
39 |
40 | public void onActivityCreated(Bundle savedInstanceState) {
41 | super.onActivityCreated(savedInstanceState);
42 |
43 | preview.setOnTouchListener(new View.OnTouchListener() {
44 | @Override
45 | public boolean onTouch(View v, MotionEvent event) {
46 | return onPublishTouch(event);
47 | }
48 | });
49 | }
50 |
51 | private boolean onPublishTouch(MotionEvent e ) {
52 |
53 | if( e.getAction() == MotionEvent.ACTION_DOWN ) {
54 | int sMode = publish.getScaleMode();
55 |
56 | sMode++;
57 | if(sMode == 3) sMode = 0;
58 |
59 | publish.setScaleMode(sMode);
60 | }
61 |
62 | return true;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/app/src/main/java/red5pro/org/testandroidproject/tests/PublishAspectTest/README.md:
--------------------------------------------------------------------------------
1 | # Publisher Aspect Ratio
2 |
3 | `R5VideoViewController.scaleMode` controls the display mode of the content that is being pushed to it. Depending on the value the content will scale to the appropriate fill value.
4 |
5 | ### Example Code
6 |
7 | - ***[PublishTest.java](../PublishTest/PublishTest.java)***
8 | - ***[PublishAspectTest.java](PublishAspectTest.java)***
9 |
10 | ## Running the example
11 |
12 | Touch the screen at any time while streaming to change the scale mode, affecting how the stream is display on the user's end.
13 |
14 | ## Using scaleMode
15 |
16 | R5VideoViewController.scaleMode has 3 potential enum values.
17 |
18 | ```sh
19 | r5_scale_to_fill: scale to fill and maintain aspect ratio (cropping will occur)
20 | r5_scale_to_fit: scale to fit inside view (letterboxing will occur)
21 | r5_scale_fill: scale to fill view (will not respect aspect ratio of video)
22 | ```
23 |
24 | By default, this value is `r5_scale_to_fill` and the android SDK handles this enum through raw int value (0,1,2) This example cycles through these values when it receives a tap.
25 |
26 | ```Java
27 | int sMode = subscribe.getScaleMode();
28 |
29 | sMode++;
30 | //A value of 3 or larger won't parse correctly to the enum, so it's reset to 0
31 | if(sMode == 3) sMode = 0;
32 |
33 | subscribe.setScaleMode(sMode);
34 | ```
35 |
36 | [PublishAspectTest.java #34](PublishAspectTest.java#L29)
37 |
--------------------------------------------------------------------------------
/app/src/main/java/red5pro/org/testandroidproject/tests/PublishAuthTest/README.md:
--------------------------------------------------------------------------------
1 | # Publisher Authentication using Red5 Pro
2 |
3 | This is an example of authenticating a Broadcast for stream playback.
4 |
5 | ### Example Code
6 |
7 | - ***[PublishTest.java](../PublishTest/PublishTest.java)***
8 | - ***[PublishAuthTest.java](PublishAuthTest.java)***
9 |
10 | > This example requires you to enable the `SimpleAuthentication` Plugin for the `live` webapp. More information: [https://www.red5pro.com/docs/](https://www.red5pro.com/docs/).
11 |
12 | ## Authenticating
13 |
14 | With the username and password known from the Red5 Pro Server `webapps/live/WEB-INF/simple-auth-plugin.credentials` file (if following the basic auth setup of the Red5 Pro Server), those values are provided to the `parameters` attribute of the `R5Configuration` instance delimited and appended with a semicolon (`;`).
15 |
16 | For example, if you have defined the authorization of a username `foo` with a password `bar`, the configuration addition would look like the following:
17 |
18 | ```java
19 | config.setParameters("username=foo;password=bar;");
20 | ```
21 |
22 | ### Example
23 |
24 | In the example, the `username` and `password` values are defined in the [test.xml](../../res/raw/test.xml#L123-L133) file entry for the *Publish - Auth* test. They are accessed and provided to the `R5Configuration` instance prior to establishing a connection:
25 |
26 | ```java
27 | String auth = "username=" + TestContent.GetPropertyString("username") + ";";
28 | auth += "password=" + TestContent.GetPropertyString("password") + ";";
29 | //Create the configuration from the values.xml
30 | R5Configuration config = new R5Configuration(R5StreamProtocol.RTSP,
31 | TestContent.GetPropertyString("host"),
32 | TestContent.GetPropertyInt("port"),
33 | TestContent.GetPropertyString("context"),
34 | TestContent.GetPropertyFloat("publish_buffer_time"),
35 | auth);
36 | config.setLicenseKey(TestContent.GetPropertyString("license_key"));
37 | config.setBundleID(getActivity().getPackageName());
38 | ```
39 |
40 | [PublishAuthTest.java #33](PublishAuthTest.java#L33)
41 |
42 | If the provided credentials match those defined for the `live` webapp in its Simple Authentication properties, then the broadcast will begin as normal. If the credentials _do not_ match, the broadcast will be rejected.
43 |
44 |
--------------------------------------------------------------------------------
/app/src/main/java/red5pro/org/testandroidproject/tests/PublishCamera2Test/README.md:
--------------------------------------------------------------------------------
1 | # Publish Camera2
2 |
3 | Android's Camera2 api offers a robust suit of controls for the camera, but it needs to be handled significatnly differently than the deprecated Camera object. While most applications can use the standard Camera object for its simplicity, this is an example of using Camera2.
4 |
5 | ### Example Code
6 |
7 | - ***[PublishTest.java](../PublishTest/PublishTest.java)***
8 | - ***[PublishCamera2Test.java](Publish2Test.java)***
9 |
10 | ## Using R5Camera2
11 |
12 | Note that the Camera2 interface was added in Android API 21, with additional features included in API 22 - meaning that the minimum API for this class is higher than the rest of our SDK.
13 |
14 | The biggest change that you'll notice from the base publish example is that unlike a camera, a CameraDevice can't be opened syncronously, and so the creation of the R5Camera2 object and triggering of the publisher has to be done after Android has returned the device to you.
15 | To call for the device, you have to get the CameraManager, ask that for the list of cameras, identify the camera you want, and then open the camera from the manager.
16 |
17 | ```Java
18 | CameraManager manager = (CameraManager)getActivity().getSystemService(Context.CAMERA_SERVICE);
19 | try {
20 | String[] camList = manager.getCameraIdList();
21 | for(String id : camList){
22 | CameraCharacteristics info = manager.getCameraCharacteristics(id);
23 | if(info.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT){
24 | camInfo = info;
25 | manager.openCamera(id, new CameraDevice.StateCallback() {
26 | @Override
27 | public void onOpened(@NonNull CameraDevice camera) {
28 | if(preview == null)
29 | return;
30 | startPublish(camera);
31 | }
32 |
33 | @Override
34 | public void onDisconnected(@NonNull CameraDevice camera) {}
35 |
36 | @Override
37 | public void onError(@NonNull CameraDevice camera, int error) {}
38 | }, null);
39 | break;
40 | }
41 | }
42 |
43 | } catch (CameraAccessException e) {
44 | e.printStackTrace();
45 | }
46 | ```
47 |
48 | [PublishCamera2Test.java #86](PublishCamera2Test.java#L86)
49 |
50 | Two things to note -
51 |
52 | * One, the CameraCharacteristics object to refer to the camera you're passing to the publisher must also be passed, so it's best to retain it here.
53 | * Two, the thread that the camera returns on won't necesarily be the UI thread, hence why the publisher is mostly set up before calling openCamera.
54 |
55 | After recieving the camera, the steps are similar to initializing an R5Camera object, with the addition of the CameraCharacteristics object in the constructor.
56 |
57 | ```Java
58 | camera2 = new R5Camera2(camera, camInfo, TestContent.GetPropertyInt("camera_width"), TestContent.GetPropertyInt("camera_height"));
59 | camera2.setBitrate(TestContent.GetPropertyInt("bitrate"));
60 | camera2.setOrientation(90);
61 | camera2.setFramerate(TestContent.GetPropertyInt("fps"));
62 |
63 | publish.attachCamera(camera2);
64 | ```
65 |
66 | [PublishCamera2Test.java #122](PublishCamera2Test.java#L122)
67 |
68 | After that, the stream can be started as normal.
69 |
70 | ## Special Addendum - Capture Request Builder
71 |
72 | In addition to the basic functionality to mirror our implementation of the Camera interface, we have also added the ability for developers to take advantage of the advanced features of the Camera2 api. To reiterate, these additional features won't be of benefit to 99% of live streaming use cases, but the option is available for those few cases that need it.
73 |
74 | R5Camera2.setCaptureRequestBuilder will accept a CaptureRequest.Builder object and open a capture session with it. For any calculations that need to know the image format, we are using ImageFormat.YUV_420_888. Note that most of the advanced functionality of Camera2 has not been implemented by the manufactures of most phones, so take care when creating a builder.
75 |
--------------------------------------------------------------------------------
/app/src/main/java/red5pro/org/testandroidproject/tests/PublishCameraDeviceOrientationTest/README.md:
--------------------------------------------------------------------------------
1 | # Publish Camera Device Orientation
2 |
3 | This example combines the `Camera Swap` and `Device Orientation` examples. For more information about either functionality, please refer to the separate tests.
4 |
5 | ### Example Code
6 | - ***[PublishCameraDeviceOrientationTest.java](PublishCameraDeviceOrientationTest.java)***
7 |
8 | ### Separate Tests
9 | - ***[Publish - Camera Swap](../PublishCameraSwapTest)***
10 | - ***[Publish - Device Orientation](../PublishDeviceOrientationTest)***
11 |
--------------------------------------------------------------------------------
/app/src/main/java/red5pro/org/testandroidproject/tests/PublishCameraSwapBlinkTest/README.md:
--------------------------------------------------------------------------------
1 | # Publish Camera Swap
2 |
3 | This example expands on the `Camera Swap` test by providing a customized form of the camera object to clear the screen while the camera device is being swapped. The front and back cameras of most devices are flipped from each other, meaning changes in camera selection often include changes in orientation. Since the changed metadata and new video data won't arrive at exactly the same time, this example is meant to prevent the subscriber from seeing upside-down images when the changes don't happen simultaneously.
4 |
5 | ### Example Code
6 |
7 | - ***[PublishTest.java](../PublishTest/PublishTest.java)***
8 | - ***[../PublishCameraSwapTest](PublishCameraSwapTest)***
9 | - ***[PublishCameraSwapBlinkTest.java](PublishCameraSwapBlinkTest.java)***
10 |
11 | ## Running the example
12 |
13 | Touch the screen at any time while streaming to switch between broadcasting from the front facing and back facing camera.
14 |
15 | ## Replacing Video Data
16 |
17 | To display a black frame instead of the image from either camera, muting the video isn't enough - the last image sent will still be displayed. Instead, the image heading to the encoder needs to be replaced with the data that's supposed to be displayed instead. While intercepting the data in `onPreviewFrame` is an option for the R5Camera, it's easier - and more universally aplicable - to replace the data as it's passed to the encoder.
18 |
19 | ```Java
20 | @Override
21 | public synchronized void encode(byte[] input, long time, boolean reset) {
22 | // Replacing data here instead of onPreviewFrame to prevent interrupting the output buffer swaps
23 | if(coverCam){
24 | input = blackData;
25 | }
26 |
27 | super.encode(input, time, reset);
28 | }
29 | ```
30 |
31 | [PublishCameraSwapBlinkTest.java #129](PublishCameraSwapBlinkTest.java#L129)
32 |
33 | `blackData` in this case is just an array of bytes that's been pre-populated with the yuv data for a black frame of the appropriate size. This technique can be used to display graphics for intermissions or other cases as well.
34 |
35 | After setting the camera to a black frame, it's important to wait at least 2 frames before and after swapping cameras, to give the system enough time to capture and apply the changes. Also remember that many devices don't allow apps to access the camera unless the code that's doing so is running on the main thread.
36 |
37 | ```Java
38 | ((R5BlinkCamera)camera).coverCam = true;
39 |
40 | // Wait for two frames, guarantees at least one black frame is sent pre- and post- swap
41 | final int waitMS = 2000/camera.getFramerate();
42 |
43 | System.out.println(" TESTING - On Publish Touch - " + waitMS + "ms set");
44 |
45 | new Thread(new Runnable() {
46 | @Override
47 | public void run() {
48 | try {
49 | Thread.sleep(waitMS);
50 | }catch (Exception e){
51 | return;
52 | }
53 |
54 | Handler mainLoop = new Handler(Looper.getMainLooper());
55 | mainLoop.post(new Runnable() {
56 | @Override
57 | public void run() {
58 |
59 | if(publish == null){
60 | return;
61 | }
62 |
63 | PublishCameraSwapBlinkTest.super.onPublishTouch(e);
64 |
65 | System.out.println(" TESTING - On Publish Touch - swapping");
66 |
67 | new Thread(new Runnable() {
68 | @Override
69 | public void run() {
70 | try{
71 | Thread.sleep(waitMS);
72 | } catch (Exception e) {
73 | return;
74 | }
75 | if(publish == null){
76 | return;
77 | }
78 |
79 | ((R5BlinkCamera)camera).coverCam = false;
80 |
81 | System.out.println(" TESTING - On Publish Touch - done");
82 |
83 | swapping = false;
84 | }
85 | }).start();
86 | }
87 | });
88 | }
89 | }).start();
90 | ```
91 |
92 | [PublishCameraSwapBlinkTest.java #28](PublishCameraSwapBlinkTest.java#L28)
--------------------------------------------------------------------------------
/app/src/main/java/red5pro/org/testandroidproject/tests/PublishCameraSwapTest/README.md:
--------------------------------------------------------------------------------
1 | # Publish Camera Swap
2 |
3 | `R5Camera.setCamera` allows the user to change the video source for a stream without interupting the broadcast.
4 |
5 | ### Example Code
6 |
7 | - ***[PublishTest.java](../PublishTest/PublishTest.java)***
8 | - ***[PublishCameraSwapTest.java](PublishCameraSwapTest.java)***
9 |
10 | ## Running the example
11 |
12 | Touch the screen at any time while streaming to switch between broadcasting from the front facing and back facing camera.
13 |
14 | ## Using R5Camera.device
15 |
16 | `R5Camera.setCamera` will allow you to hot-swap sources for the stream. Once streaming, simply call:
17 |
18 | ```Java
19 | R5Camera publishCam = (R5Camera)publish.getVideoSource();
20 | ```
21 |
22 | [PublishCameraSwapTest.java #32](PublishCameraSwapTest.java#L32)
23 |
24 | ```Java
25 | publishCam.setCamera(newCam);
26 | ```
27 |
28 | [PublishCameraSwapTest.java #59](PublishCameraSwapTest.java#L59)
--------------------------------------------------------------------------------
/app/src/main/java/red5pro/org/testandroidproject/tests/PublishCustomMicTest/PublishCustomMicTest.java:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright © 2015 Infrared5, Inc. All rights reserved.
3 | //
4 | // The accompanying code comprising examples for use solely in conjunction with Red5 Pro (the "Example Code")
5 | // is licensed to you by Infrared5 Inc. in consideration of your agreement to the following
6 | // license terms and conditions. Access, use, modification, or redistribution of the accompanying
7 | // code constitutes your acceptance of the following license terms and conditions.
8 | //
9 | // Permission is hereby granted, free of charge, to you to use the Example Code and associated documentation
10 | // files (collectively, the "Software") without restriction, including without limitation the rights to use,
11 | // copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
12 | // persons to whom the Software is furnished to do so, subject to the following conditions:
13 | //
14 | // The Software shall be used solely in conjunction with Red5 Pro. Red5 Pro is licensed under a separate end
15 | // user license agreement (the "EULA"), which must be executed with Infrared5, Inc.
16 | // An example of the EULA can be found on our website at: https://account.red5pro.com/assets/LICENSE.txt.
17 | //
18 | // The above copyright notice and this license shall be included in all copies or portions of the Software.
19 | //
20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
21 | // NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 | // NONINFRINGEMENT. IN NO EVENT SHALL INFRARED5, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 | //
26 | package red5pro.org.testandroidproject.tests.PublishCustomMicTest;
27 |
28 | import com.red5pro.streaming.source.R5Microphone;
29 |
30 | import red5pro.org.testandroidproject.tests.PublishTest.PublishTest;
31 |
32 | /**
33 | * Created by davidHeimann on 12/22/17.
34 | */
35 |
36 | public class PublishCustomMicTest extends PublishTest {
37 |
38 | @Override
39 | protected void attachMic() {
40 |
41 | R5Microphone mic = new gainWobbleMic();
42 | publish.attachMic(mic);
43 | }
44 |
45 | public class gainWobbleMic extends R5Microphone {
46 |
47 | private float gain = 1.0f;
48 | private int mod = 1;
49 | private double lastTime = 0;
50 |
51 | @Override
52 | public void processData(byte[] samples, double streamtimeMill) {
53 |
54 | modifyGain(streamtimeMill - lastTime);
55 | lastTime = streamtimeMill;
56 |
57 | int s;
58 | for(int i = 0; i < samples.length; i++){
59 |
60 | s = (int) (samples[i] * gain);
61 | samples[i] = (byte) Math.min(s, 0xff);
62 | }
63 |
64 | super.processData(samples, streamtimeMill);
65 | }
66 |
67 | private void modifyGain(double time){
68 | //causes the gain to increase to double volume and decrease to 0 volume, then back
69 | gain += mod * (time/2000);
70 | if( gain >= 2 || gain <= 0 ){
71 | System.out.println("gain at: " + gain);
72 | gain = Math.max(2.0f * mod, 0.0f);
73 | mod *= -1;
74 | }
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/app/src/main/java/red5pro/org/testandroidproject/tests/PublishCustomMicTest/Readme.md:
--------------------------------------------------------------------------------
1 | # Custom Microphone Publishing
2 |
3 | This example demonstrates passing custom video data into the R5Stream.
4 |
5 | ### Example Code
6 |
7 | - ***[PublishTest.java](../PublishTest/PublishTest.java)***
8 | - ***[PublishCustomMicTest.java](PublishCustomMicTest.java)***
9 |
10 | ### Setup
11 |
12 | To view this example, you simply need to open the example and subscribe to your stream from a second device. All video will be recorded, and the microphone audio will have its volume modified before being sent out.
13 |
14 | #### Attach a Custom Audio Source
15 |
16 | Instead of using an R5Microphone, this example uses a custom video source, the `gainWobbleMic`. This increases and decreases the gain between double volume to muted and back. It does this by extending the R5Microphone class and intercepting the `processData` method.
17 |
18 | This method recieves a byte array of raw audio samples - each byte being a single, mono sample - and a timestamp in milliseconds with the 0 point being the start of the stream. The array is passed by reference, so it needs to be modified in place - by assigning new values to items in the array, and not assiging a new array - which would just overwrite the reference.
19 |
20 | ```Java
21 | int s;
22 | for(int i = 0; i < samples.length; i++){
23 |
24 | s = (int) (samples[i] * gain);
25 | samples[i] = (byte) Math.min(s, 0xff);
26 | }
27 | ```
28 |
29 | [PublishCustomMicTest.java #82](PublishCustomMicTest.java#L82)
30 |
31 | This example amplifies the value of each byte according to the gain value - clamping the value to keep it from wrapping around when being converted back to a byte. This function could be used as a timing device to provide completely separate audio.
32 |
--------------------------------------------------------------------------------
/app/src/main/java/red5pro/org/testandroidproject/tests/PublishCustomSourceTest/Readme.md:
--------------------------------------------------------------------------------
1 | # Custom Publishing on Red5 Pro
2 |
3 | This example demonstrates passing custom video data into the R5Stream.
4 |
5 | ### Example Code
6 |
7 | - ***[PublishCustomSourceTest.java](PublishCustomSourceTest.java)***
8 | - ***[CustomVideoSource.java](CustomVideoSource.java)***
9 |
10 | ### Setup
11 |
12 | To view this example, you simply need to open the example and subscribe to your stream from a second device. All audio will be recorded, and instead of camera input, a simply plasma style effect is rendered.
13 |
14 | #### Attach a Custom Video Source
15 |
16 | Instead of using an R5Camera, this example uses a custom video source, the `CustomVideoSource`. This device
17 |
18 | ```Java
19 | CustomVideoSource source = new CustomVideoSource();
20 | publish.attachCamera(source);
21 | ```
22 |
23 | [PublishCustomSourceTest.java #54](PublishCustomSourceTest.java#L54)
24 |
25 | This device automatically polls and pushes to the encoder when new pixels are ready to be published. There are several steps that are needed to properly feed data to the encoder.
26 |
27 | 1. **Make sure all bytes are in the YUV420 or YV12 pixel format.** `CustomVideoSource` uses RGBA data, so it has a special function `encodeYUV420` which converts RGB data to this format. This method can be seen at [CustomVideoSource.java #47](CustomVideoSource.java#L47).
28 | 2. **Call `prepareFrame`**. This method will convert the YUV data into the proper format for the encoder. `CustomVideoSource` has two buffers, and copies the properly prepared frames to the output buffer at [CustomVideoSource.java #183](CustomVideoSource.java#L183).
29 | 3. **Get the timestamp.** The timestamp can be gotten from the AudioEngine if you are publishing audio, or can be localled tracked. [CustomVideoSource.java #187](CustomVideoSource.java#L187).
30 | 4. **Encode the data!** This last call to `encode` will send the data to the encoder and pass to the stream when ready. [CustomVideoSource.java #192](CustomVideoSource.java#L192).
31 |
32 |
--------------------------------------------------------------------------------
/app/src/main/java/red5pro/org/testandroidproject/tests/PublishEncryptedTest/PublishEncryptedTest.java:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright © 2015 Infrared5, Inc. All rights reserved.
3 | //
4 | // The accompanying code comprising examples for use solely in conjunction with Red5 Pro (the "Example Code")
5 | // is licensed to you by Infrared5 Inc. in consideration of your agreement to the following
6 | // license terms and conditions. Access, use, modification, or redistribution of the accompanying
7 | // code constitutes your acceptance of the following license terms and conditions.
8 | //
9 | // Permission is hereby granted, free of charge, to you to use the Example Code and associated documentation
10 | // files (collectively, the "Software") without restriction, including without limitation the rights to use,
11 | // copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
12 | // persons to whom the Software is furnished to do so, subject to the following conditions:
13 | //
14 | // The Software shall be used solely in conjunction with Red5 Pro. Red5 Pro is licensed under a separate end
15 | // user license agreement (the "EULA"), which must be executed with Infrared5, Inc.
16 | // An example of the EULA can be found on our website at: https://account.red5pro.com/assets/LICENSE.txt.
17 | //
18 | // The above copyright notice and this license shall be included in all copies or portions of the Software.
19 | //
20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
21 | // NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 | // NONINFRINGEMENT. IN NO EVENT SHALL INFRARED5, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 | //
26 | package red5pro.org.testandroidproject.tests.PublishEncryptedTest;
27 |
28 | import com.red5pro.streaming.R5Connection;
29 | import com.red5pro.streaming.R5Stream;
30 | import com.red5pro.streaming.R5StreamProtocol;
31 | import com.red5pro.streaming.config.R5Configuration;
32 |
33 | import red5pro.org.testandroidproject.tests.PublishTest.PublishTest;
34 | import red5pro.org.testandroidproject.tests.TestContent;
35 |
36 | public class PublishEncryptedTest extends PublishTest {
37 |
38 | @Override
39 | protected void publish(){
40 |
41 | String b = getActivity().getPackageName();
42 |
43 | //Create the configuration from the values.xml
44 | R5Configuration config = new R5Configuration(R5StreamProtocol.SRTP,
45 | TestContent.GetPropertyString("host"),
46 | TestContent.GetPropertyInt("port"),
47 | TestContent.GetPropertyString("context"),
48 | TestContent.GetPropertyFloat("publish_buffer_time"));
49 | config.setLicenseKey(TestContent.GetPropertyString("license_key"));
50 | config.setBundleID(b);
51 |
52 | String params = TestContent.getConnectionParams();
53 | if (params != null) {
54 | config.setParameters(params);
55 | }
56 |
57 | R5Connection connection = new R5Connection(config);
58 |
59 | //setup a new stream using the connection
60 | publish = new R5Stream(connection);
61 |
62 | publish.audioController.sampleRate = TestContent.GetPropertyInt("sample_rate");
63 |
64 | //show all logging
65 | publish.setLogLevel(R5Stream.LOG_LEVEL_DEBUG);
66 |
67 | if(TestContent.GetPropertyBool("audio_on")) {
68 | //attach a microphone
69 | attachMic();
70 | }
71 |
72 | preview.attachStream(publish);
73 |
74 | if(TestContent.GetPropertyBool("video_on")) {
75 | //attach a camera video source
76 | attachCamera();
77 | }
78 |
79 | preview.showDebugView(TestContent.GetPropertyBool("debug_view"));
80 |
81 | publish.setListener(this);
82 | publish.publish(TestContent.GetPropertyString("stream1"), getPublishRecordType());
83 |
84 | if(TestContent.GetPropertyBool("video_on")) {
85 | cam.startPreview();
86 | }
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/app/src/main/java/red5pro/org/testandroidproject/tests/PublishEncryptedTest/README.md:
--------------------------------------------------------------------------------
1 | # Adding security to Red5 Pro streams
2 |
3 | While a lot of streaming applications are intended to be as public as possible, many are intended for more descrete audiences - or decidedly confidential. For those situations, SRTP can give a piece of mind that traffic can't be spyed on uninvited.
4 |
5 | > **NOTE:** SRTP Support requires Red5 Pro Server version 5.5.0 or higher
6 |
7 | ### Example Code
8 |
9 | - ***[PublishTest.java](../PublishTest/PublishTest.java)***
10 | - ***[PublishEncryptedTest.java](PublishEncryptedTest.java)***
11 |
12 | ## SRTP
13 |
14 | The Red5 Pro SDK has included the option to wrap its streams in `SRTP` - a Secure variation of the `RTP` (Real-time Transport Protocol) that is normally used to wrap `RTSP` (Real-time Streaming Protocol) that the SDK operates on. Specifically, once negotiation with the server is complete, everything sent between the SDK and server (or vice versa) is encrypted and authenticated to ensure that a third party can't view the stream or modify data without detection.
15 |
16 | Also, as part of the SRTP specification, we support "null key" SRTP. Refered to in the sdk as `Null SRTP` - it's essentially taking the authentication protection to prevent outside tampering with the stream in situations that don't require the extra overhead for the view-protection of encryption.
17 |
18 | Note that while the encryption suite used is relatively fast where cryptograhpy is concerned, it does still introduce some overhead. Even Null SRTP still requires processing all data before transmition, and mobile devices aren't the most powerful of computers. This overhead will scale roughly with bitrate settings, and may lower the framerate of a stream.
19 |
20 | ### Enable Encryption
21 |
22 | As complicated as encryption is, it's implementation couldn't be simpler - simply set the `protocol` property of the R5Configuration (the first value of its constructor) to the correct value before initializing the connection and the SDK will take care of the rest.
23 |
24 | ```Java
25 | R5Configuration config = new R5Configuration(R5StreamProtocol.SRTP,
26 | ```
27 |
28 | [PublishEncryptedTest.java #19](PublishEncryptedTest.java#L19)
29 |
30 | To set Null SRTP instead, use `NULL_SRTP` - and of course, the default of `RTSP` is still available where security isn't such a concern.
31 |
32 | ### New Events
33 |
34 | As part of the new protocols, two new events have been added to differentiate between an issue specific to the SRTP setup and the SDK in general.
35 |
36 | `R5ConnectionEvent.SRTP_KEY_GEN_ERROR` - This indicates that something has prevented the device from generating its part of the key exchange. The chance of seeing this error should be zero - barring a manufacturing fault or software malfunction.
37 |
38 | `R5ConnectionEvent.SRTP_KEY_HANDLE_ERROR` - This indicates that there has been a fault between the server and the SDK. Either that there's been some fault that prevented the key exchange from happening cleanly - or that the server is using an old version and doesn't support SRTP.
39 |
40 | For both of these errors, the message that accompanies them will include more detail on what exactly hasn't worked.
41 |
--------------------------------------------------------------------------------
/app/src/main/java/red5pro/org/testandroidproject/tests/PublishHQAudioTest/README.md:
--------------------------------------------------------------------------------
1 | # Publishing High Quality Audio
2 |
3 | `R5AudioController.sampleRate` allows the user to increase the number of times per second that a device grabs a signal from the microphone. Higher values can improve the quality of a broadcast.
4 |
5 | ### Example Code
6 |
7 | - ***[PublishTest.java](../PublishTest/PublishTest.java)***
8 | - ***[PublishHQAudioTest.java](PublishHQAudioTest.java)***
9 |
10 | ## Using R5Microphone.sampleRate
11 |
12 | `R5AudioController.sampleRate` is by default set to 8000 - or 8khz, which is decent for most applications, but far from archival quality, especially when it comes to music. Note that setting this value higher will also require a higher bitrate. Increasing the bitrate without increasing the sample rate will only get you so far in reducing compression on the audio, but increasing the sample rate without increasing the bitrate will increase how much each sample is compressed, which could lead to a worse sound.
13 |
14 | ```Java
15 | mic.setBitRate(128);//kbps
16 | R5AudioController.getInstance().sampleRate = 44100;//hz (samples/second)
17 | ```
18 |
19 | [PublishHQAudioTest.java #65](PublishHQAudioTest.java#L65)
20 |
21 | This must be set before you start publishing, and changing the value after calling `R5Stream.publish` will not effect the sample rate.
22 |
23 | ## Receiving HQ Audio
24 |
25 | Android has issues playing audio from raw data, and thus currently can't play back audio at sample rates other than 8khz. Other sample rates will be up or downsampled to play at that rate.
26 |
27 | ## Two Way and HQ Audio
28 |
29 | Two way applications require echo cancellation to minimize feedback, and in order for the device to cancel playback that's received by the microphone, the two signals need to meet certain settings. In order for it to work correctly, the sample rates of the publisher and subscriber should be the same, and since playback is locked to 8khz, the publisher should be as well.
30 |
--------------------------------------------------------------------------------
/app/src/main/java/red5pro/org/testandroidproject/tests/PublishImageTest/PublishImageTest.java:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright © 2015 Infrared5, Inc. All rights reserved.
3 | //
4 | // The accompanying code comprising examples for use solely in conjunction with Red5 Pro (the "Example Code")
5 | // is licensed to you by Infrared5 Inc. in consideration of your agreement to the following
6 | // license terms and conditions. Access, use, modification, or redistribution of the accompanying
7 | // code constitutes your acceptance of the following license terms and conditions.
8 | //
9 | // Permission is hereby granted, free of charge, to you to use the Example Code and associated documentation
10 | // files (collectively, the "Software") without restriction, including without limitation the rights to use,
11 | // copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
12 | // persons to whom the Software is furnished to do so, subject to the following conditions:
13 | //
14 | // The Software shall be used solely in conjunction with Red5 Pro. Red5 Pro is licensed under a separate end
15 | // user license agreement (the "EULA"), which must be executed with Infrared5, Inc.
16 | // An example of the EULA can be found on our website at: https://account.red5pro.com/assets/LICENSE.txt.
17 | //
18 | // The above copyright notice and this license shall be included in all copies or portions of the Software.
19 | //
20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
21 | // NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 | // NONINFRINGEMENT. IN NO EVENT SHALL INFRARED5, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 | //
26 | package red5pro.org.testandroidproject.tests.PublishImageTest;
27 |
28 | import android.graphics.Bitmap;
29 | import android.graphics.Matrix;
30 | import android.os.Bundle;
31 | import android.view.MotionEvent;
32 | import android.view.View;
33 | import android.widget.FrameLayout;
34 | import android.widget.ImageView;
35 |
36 | import red5pro.org.testandroidproject.tests.PublishTest.PublishTest;
37 |
38 | /**
39 | * Created by davidHeimann on 2/10/16.
40 | */
41 | public class PublishImageTest extends PublishTest {
42 | ImageView screenShot;
43 |
44 | @Override
45 | public void onActivityCreated(Bundle savedInstanceState) {
46 | super.onActivityCreated(savedInstanceState);
47 |
48 | preview.setOnTouchListener(new View.OnTouchListener() {
49 | @Override
50 | public boolean onTouch(View v, MotionEvent event) {
51 | return onSubscribeTouch(event);
52 | }
53 | });
54 | }
55 |
56 | private boolean onSubscribeTouch( MotionEvent e ){
57 |
58 | if( e.getAction() == MotionEvent.ACTION_DOWN ){
59 | if( screenShot != null ){
60 | ((FrameLayout)preview.getParent()).removeView(screenShot);
61 | }
62 | screenShot = new ImageView( preview.getContext() );
63 | FrameLayout.LayoutParams position = new FrameLayout.LayoutParams( preview.getWidth()/2, preview.getHeight()/2 );
64 | position.setMargins(preview.getWidth() / 2, preview.getHeight() / 2, 0, 0);
65 | screenShot.setLayoutParams(position);
66 |
67 | screenShot.setScaleType(ImageView.ScaleType.FIT_CENTER);
68 |
69 | Bitmap streamImage = publish.getStreamImage();
70 | Matrix manip = new Matrix();
71 | manip.setRotate(camOrientation);
72 | streamImage = Bitmap.createBitmap(streamImage, 0, 0, streamImage.getWidth(), streamImage.getHeight(), manip, true );
73 | manip.setScale( -1f, 1f );
74 | streamImage = Bitmap.createBitmap(streamImage, 0, 0, streamImage.getWidth(), streamImage.getHeight(), manip, true );
75 |
76 | screenShot.setImageBitmap(streamImage);
77 |
78 | ((FrameLayout)preview.getParent()).addView(screenShot);
79 | }
80 |
81 | return true;
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/app/src/main/java/red5pro/org/testandroidproject/tests/PublishImageTest/README.md:
--------------------------------------------------------------------------------
1 | # Publish Image Capture
2 |
3 | `R5Stream.getStreamImage` allows the user to capture a screenshot of the stream at any time.
4 |
5 | ### Example Code
6 |
7 | - ***[PublishTest.java](../PublishTest/PublishTest.java)***
8 | - ***[PublishImageTest.java](PublishImageTest.java)***
9 |
10 | ## Running the example
11 |
12 | Touch the screen at any time while streaming to popup a temporary overlay containing the UIImage that is returned from the Red5 Pro SDK.
13 |
14 | ## Using getStreamImage
15 |
16 | `R5Stream.getStreamImage` returns a UIImage containing a screenshot of the current stream. The image dimensions match the incoming stream dimensions, and contain RGB data. Once streaming, simply call:
17 |
18 | ```Java
19 | Bitmap streamImage = publish.getStreamImage();
20 | ```
21 |
22 | [PublishImageTest.java #44](PublishImageTest.java#L44)
23 |
24 |
25 | The UIImage can be saved to disk, displayed with a UIImageView, or processed in any way that is needed.
--------------------------------------------------------------------------------
/app/src/main/java/red5pro/org/testandroidproject/tests/PublishLocalRecordTest/PublishLocalRecordTest.java:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright © 2015 Infrared5, Inc. All rights reserved.
3 | //
4 | // The accompanying code comprising examples for use solely in conjunction with Red5 Pro (the "Example Code")
5 | // is licensed to you by Infrared5 Inc. in consideration of your agreement to the following
6 | // license terms and conditions. Access, use, modification, or redistribution of the accompanying
7 | // code constitutes your acceptance of the following license terms and conditions.
8 | //
9 | // Permission is hereby granted, free of charge, to you to use the Example Code and associated documentation
10 | // files (collectively, the "Software") without restriction, including without limitation the rights to use,
11 | // copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
12 | // persons to whom the Software is furnished to do so, subject to the following conditions:
13 | //
14 | // The Software shall be used solely in conjunction with Red5 Pro. Red5 Pro is licensed under a separate end
15 | // user license agreement (the "EULA"), which must be executed with Infrared5, Inc.
16 | // An example of the EULA can be found on our website at: https://account.red5pro.com/assets/LICENSE.txt.
17 | //
18 | // The above copyright notice and this license shall be included in all copies or portions of the Software.
19 | //
20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
21 | // NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 | // NONINFRINGEMENT. IN NO EVENT SHALL INFRARED5, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 | //
26 | package red5pro.org.testandroidproject.tests.PublishLocalRecordTest;
27 |
28 | import com.red5pro.streaming.R5Stream;
29 |
30 | import java.util.HashMap;
31 | import java.util.Map;
32 |
33 | import red5pro.org.testandroidproject.tests.PublishTest.PublishTest;
34 | import red5pro.org.testandroidproject.tests.TestContent;
35 |
36 | /**
37 | * Created by davidHeimann on 7/28/17.
38 | */
39 |
40 | public class PublishLocalRecordTest extends PublishTest {
41 |
42 | @Override
43 | protected void publish() {
44 | super.publish();
45 |
46 | Map props = new HashMap<>();
47 | props.put(R5Stream.VideoBitrateKey, TestContent.GetPropertyInt("bitrate") * 2);
48 | props.put(R5Stream.AudioBitrateKey, publish.getAudioSource().getBitRate() * 2);
49 | //other potential properties (all properties are optional):
50 | // props.put(R5Stream.RecordDirectoryKey, "some/location/on/this/device"); //where to store the media
51 | // props.put(R5Stream.RecordMediaScanKey, true); //should the media be scanned into the OS's media apps (default: true)
52 |
53 | publish.beginLocalRecordingWithProperties(getActivity().getApplicationContext(), "r5pro/testRecord", props);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/app/src/main/java/red5pro/org/testandroidproject/tests/PublishOrientationTest/PublishOrientationTest.java:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright © 2015 Infrared5, Inc. All rights reserved.
3 | //
4 | // The accompanying code comprising examples for use solely in conjunction with Red5 Pro (the "Example Code")
5 | // is licensed to you by Infrared5 Inc. in consideration of your agreement to the following
6 | // license terms and conditions. Access, use, modification, or redistribution of the accompanying
7 | // code constitutes your acceptance of the following license terms and conditions.
8 | //
9 | // Permission is hereby granted, free of charge, to you to use the Example Code and associated documentation
10 | // files (collectively, the "Software") without restriction, including without limitation the rights to use,
11 | // copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
12 | // persons to whom the Software is furnished to do so, subject to the following conditions:
13 | //
14 | // The Software shall be used solely in conjunction with Red5 Pro. Red5 Pro is licensed under a separate end
15 | // user license agreement (the "EULA"), which must be executed with Infrared5, Inc.
16 | // An example of the EULA can be found on our website at: https://account.red5pro.com/assets/LICENSE.txt.
17 | //
18 | // The above copyright notice and this license shall be included in all copies or portions of the Software.
19 | //
20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
21 | // NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 | // NONINFRINGEMENT. IN NO EVENT SHALL INFRARED5, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 | //
26 | package red5pro.org.testandroidproject.tests.PublishOrientationTest;
27 |
28 | import android.os.Bundle;
29 | import android.view.MotionEvent;
30 | import android.view.View;
31 |
32 | import com.red5pro.streaming.source.R5Camera;
33 |
34 | import red5pro.org.testandroidproject.tests.PublishTest.PublishTest;
35 |
36 | /**
37 | * Created by davidHeimann on 2/10/16.
38 | */
39 | public class PublishOrientationTest extends PublishTest {
40 |
41 | public void onActivityCreated(Bundle savedInstanceState) {
42 | super.onActivityCreated(savedInstanceState);
43 |
44 | preview.setOnTouchListener(new View.OnTouchListener() {
45 | @Override
46 | public boolean onTouch(View v, MotionEvent event) {
47 | return onPublishTouch(event);
48 | }
49 | });
50 | }
51 |
52 | private boolean onPublishTouch( MotionEvent e ) {
53 |
54 | if( e.getAction() == MotionEvent.ACTION_UP && publish != null) {
55 | R5Camera publishCam = (R5Camera)publish.getVideoSource();
56 | publishCam.setOrientation( publishCam.getOrientation() + 90 );
57 | }
58 |
59 | return true;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/app/src/main/java/red5pro/org/testandroidproject/tests/PublishOrientationTest/README.md:
--------------------------------------------------------------------------------
1 | # Publish Orientation
2 |
3 | `R5Camera.orientation` allows the user to rotate the video source for a stream without interupting the broadcast.
4 |
5 | ### Example Code
6 |
7 | - ***[PublishTest.java](../PublishTest/PublishTest.java)***
8 | - ***[PublishOrientationTest.java](PublishOrientationTest.java)***
9 |
10 | ## Running the example
11 |
12 | Touch the screen at any time while streaming to rotate the video source by 90 degrees. It's sugested that you verify this change with a separate device.
13 |
14 | ## Using R5Camera.orientation
15 |
16 | `R5Camera.orientation` will tell you how much the current video source is rotated from how it's coming into the application. By getting the instance of R5Camera attached to the R5Stream object and changing its orientation property, this can be modified live for the stream. Once streaming, simply call:
17 |
18 | ```Swift
19 | R5Camera publishCam = (R5Camera)publish.getVideoSource();
20 | publishCam.setOrientation( publishCam.getOrientation() + 90 );
21 | ```
22 |
23 | [PublishOrientationTest.java #30](PublishOrientationTest.java#L30)
--------------------------------------------------------------------------------
/app/src/main/java/red5pro/org/testandroidproject/tests/PublishPauseTest/README.md:
--------------------------------------------------------------------------------
1 | # Publish Mute/Unmute
2 |
3 | The `R5Stream:restrainAudio` and `R5Stream:restrainVideo` methods allow for a broadcast stream to be muted and unmuted of audio and video separately.
4 |
5 | ### Example Code
6 |
7 | - ***[PublishPauseTest.java](PublishPauseTest.java)***
8 |
9 | ## Running the example
10 |
11 | The `PublishPauseTest` launches in a broadcast session with Audio & Video inputs enabled and streaming.
12 |
13 | Touch the screen at any time while streaming to toggle between muted and unmuted states of each Audio and Video input. Subscribe to the stream on another device to see how the muted states affect the broadcast.
14 |
15 | The toggle sequence is as follows when you tap the screen multiple times:
16 |
17 | 1. The first tap will mute the audio being sent.
18 | 2. The second tap will unmute the audio from _Tap 1_ and mute the video.
19 | 3. The third tap will mute the audio again - muting both video and audio at the same time.
20 | 4. The fourth tap will unmute both audio and video, returning to its original state on launch of test and broadcast.
21 |
22 | ## Using RStream:restrainAudio and R5Stream:restrainVideo
23 |
24 | `R5Stream:restrainAudio` and `R5Stream:restrainVideo` are methods that can be invoked to mute or unmute the audio and video of a stream, repectively. They each take a `boolean` argument. Passing `true` will mute the media in the stream, passing `false` will unmute the media.
25 |
26 | ```java
27 | preview.setOnTouchListener(new View.OnTouchListener() {
28 | @Override
29 | public boolean onTouch(View v, MotionEvent event) {
30 |
31 | if (event.getAction() == MotionEvent.ACTION_DOWN) {
32 |
33 | muteEnum = muteEnum + 1;
34 | if (muteEnum > 3) {
35 | muteEnum = 0;
36 | }
37 |
38 | switch (muteEnum) {
39 | case 1:
40 | // mute audio
41 | publish.restrainAudio(true);
42 | publish.restrainVideo(false);
43 | Log.d("PublisherPause", "Mute Audio");
44 | break;
45 | case 2:
46 | // mute video
47 | publish.restrainAudio(false);
48 | publish.restrainVideo(true);
49 | Log.d("PublisherPause", "Mute Video");
50 | break;
51 | case 3:
52 | // mute audio & video
53 | publish.restrainAudio(true);
54 | publish.restrainVideo(true);
55 | Log.d("PublisherPause", "Mute Audio & Video");
56 | break;
57 | case 0:
58 | // unmute audio & video
59 | publish.restrainAudio(false);
60 | publish.restrainVideo(false);
61 | Log.d("PublisherPause", "Umute all");
62 | break;
63 | }
64 |
65 | }
66 |
67 | return true;
68 | }
69 | });
70 | ```
71 |
72 | [PublishPauseTest.java #31](PublishPauseTest.javat#L31)
73 |
74 | ## Listening for mute on a Subscriber stream
75 |
76 | Calling the `R5Stream:restrainAudio` and `R5Stream:restrainVideo` methods change the `streamingMode` value of the metadata that is additionally broadcast to subscribers of the stream. As a subscriber, you can listen for their respective mute and unmute states of a broadcast stream from the status codes defined for [R5ConnectionListener](https://www.red5pro.com/docs/static/android-streaming/interfacecom_1_1red5pro_1_1streaming_1_1event_1_1_r5_connection_listener.html).
77 |
78 |
--------------------------------------------------------------------------------
/app/src/main/java/red5pro/org/testandroidproject/tests/PublishRemoteCallTest/PublishRemoteCallTest.java:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright © 2015 Infrared5, Inc. All rights reserved.
3 | //
4 | // The accompanying code comprising examples for use solely in conjunction with Red5 Pro (the "Example Code")
5 | // is licensed to you by Infrared5 Inc. in consideration of your agreement to the following
6 | // license terms and conditions. Access, use, modification, or redistribution of the accompanying
7 | // code constitutes your acceptance of the following license terms and conditions.
8 | //
9 | // Permission is hereby granted, free of charge, to you to use the Example Code and associated documentation
10 | // files (collectively, the "Software") without restriction, including without limitation the rights to use,
11 | // copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
12 | // persons to whom the Software is furnished to do so, subject to the following conditions:
13 | //
14 | // The Software shall be used solely in conjunction with Red5 Pro. Red5 Pro is licensed under a separate end
15 | // user license agreement (the "EULA"), which must be executed with Infrared5, Inc.
16 | // An example of the EULA can be found on our website at: https://account.red5pro.com/assets/LICENSE.txt.
17 | //
18 | // The above copyright notice and this license shall be included in all copies or portions of the Software.
19 | //
20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
21 | // NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 | // NONINFRINGEMENT. IN NO EVENT SHALL INFRARED5, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 | //
26 | package red5pro.org.testandroidproject.tests.PublishRemoteCallTest;
27 |
28 | import android.os.Bundle;
29 | import android.view.MotionEvent;
30 | import android.view.View;
31 |
32 | import com.red5pro.streaming.event.R5ConnectionEvent;
33 | import com.red5pro.streaming.event.R5ConnectionListener;
34 |
35 | import java.util.Hashtable;
36 |
37 | import red5pro.org.testandroidproject.tests.PublishTest.PublishTest;
38 |
39 | /**
40 | * Created by davidHeimann on 4/25/16.
41 | */
42 | public class PublishRemoteCallTest extends PublishTest {
43 |
44 | @Override
45 | public void onActivityCreated(Bundle savedInstanceState) {
46 | super.onActivityCreated(savedInstanceState);
47 |
48 | publish.setListener(this);
49 | }
50 |
51 | @Override
52 | public void onConnectionEvent(R5ConnectionEvent r5ConnectionEvent) {
53 |
54 | super.onConnectionEvent(r5ConnectionEvent);
55 | if(r5ConnectionEvent == R5ConnectionEvent.START_STREAMING ) {
56 | preview.setOnTouchListener(new View.OnTouchListener() {
57 | @Override
58 | public boolean onTouch(View v, MotionEvent event) {
59 |
60 | if (event.getAction() == MotionEvent.ACTION_DOWN) {
61 | Hashtable