diff --git a/.gitmodules b/.gitmodules index c6211ba1..ff74e77f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,6 +7,12 @@ [submodule "3rdpart/jsoncpp"] path = 3rdpart/jsoncpp url = https://gitee.com/mirrors/jsoncpp.git +[submodule "3rdpart/openssl"] + path = 3rdpart/openssl + url = https://gitee.com/varlet_mirror/openssl-1.1.1k.git [submodule "www/webassist"] path = www/webassist url = https://gitee.com/victor1002/zlm_webassist +[submodule "3rdpart/libsrtp"] + path = 3rdpart/libsrtp + url = https://github.com/cisco/libsrtp.git diff --git a/.gitmodules_github b/.gitmodules_github index 87b576ee..fb47992c 100644 --- a/.gitmodules_github +++ b/.gitmodules_github @@ -7,6 +7,9 @@ [submodule "3rdpart/jsoncpp"] path = 3rdpart/jsoncpp url = https://github.com/open-source-parsers/jsoncpp.git +[submodule "3rdpart/openssl"] + path = 3rdpart/openssl + url = https://gitee.com/varlet_mirror/openssl-1.1.1k.git [submodule "www/webassist"] path = www/webassist url = https://github.com/1002victor/zlm_webassist \ No newline at end of file diff --git a/3rdpart/CMakeLists.txt b/3rdpart/CMakeLists.txt index f55fc6c7..60d968a9 100644 --- a/3rdpart/CMakeLists.txt +++ b/3rdpart/CMakeLists.txt @@ -197,6 +197,7 @@ else() _CRT_SECURE_NO_WARNINGS _WINSOCK_DEPRECATED_NO_WARNINGS) endif() + # 添加库 add_library(zltoolkit STATIC ${ToolKit_SRC_LIST}) add_library(ZLMediaKit::ToolKit ALIAS zltoolkit) diff --git a/3rdpart/libsrtp b/3rdpart/libsrtp new file mode 160000 index 00000000..9a139f5c --- /dev/null +++ b/3rdpart/libsrtp @@ -0,0 +1 @@ +Subproject commit 9a139f5c8ba7629b3c0ac9cc7bbf74e4bf10313a diff --git a/3rdpart/openssl b/3rdpart/openssl new file mode 160000 index 00000000..91157f7e --- /dev/null +++ b/3rdpart/openssl @@ -0,0 +1 @@ +Subproject commit 91157f7e572916a7e5b910bae2e0f71b13a7c35e diff --git a/Android/app/build.gradle b/Android/app/build.gradle index 4fb582df..a241babd 100644 --- a/Android/app/build.gradle +++ b/Android/app/build.gradle @@ -1,7 +1,7 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 28 + compileSdkVersion 30 //ndkVersion "25.1.xxx" defaultConfig { applicationId "com.zlmediakit.demo" @@ -33,6 +33,21 @@ android { path "src/main/cpp/CMakeLists.txt" } } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } +// kotlinOptions { +// jvmTarget = "17" +// } + +// buildFeatures { +// viewBinding = true +// buildConfig = true +// } + + + } dependencies { diff --git a/Android/app/libs/arm64-v8a/libcrypto.a b/Android/app/libs/arm64-v8a/libcrypto.a new file mode 100644 index 00000000..a1cb98f0 Binary files /dev/null and b/Android/app/libs/arm64-v8a/libcrypto.a differ diff --git a/Android/app/libs/arm64-v8a/libcrypto.so b/Android/app/libs/arm64-v8a/libcrypto.so new file mode 100644 index 00000000..28b8fefe Binary files /dev/null and b/Android/app/libs/arm64-v8a/libcrypto.so differ diff --git a/Android/app/libs/arm64-v8a/libsrtp2.a b/Android/app/libs/arm64-v8a/libsrtp2.a new file mode 100644 index 00000000..b951b0c7 Binary files /dev/null and b/Android/app/libs/arm64-v8a/libsrtp2.a differ diff --git a/Android/app/libs/arm64-v8a/libsrtp2.so b/Android/app/libs/arm64-v8a/libsrtp2.so new file mode 100644 index 00000000..54cb8a24 Binary files /dev/null and b/Android/app/libs/arm64-v8a/libsrtp2.so differ diff --git a/Android/app/libs/arm64-v8a/libssl.a b/Android/app/libs/arm64-v8a/libssl.a new file mode 100644 index 00000000..e586e151 Binary files /dev/null and b/Android/app/libs/arm64-v8a/libssl.a differ diff --git a/Android/app/libs/arm64-v8a/libssl.so b/Android/app/libs/arm64-v8a/libssl.so new file mode 100644 index 00000000..af218036 Binary files /dev/null and b/Android/app/libs/arm64-v8a/libssl.so differ diff --git a/Android/app/src/main/cpp/CMakeLists.txt b/Android/app/src/main/cpp/CMakeLists.txt index 6db855a6..81195b61 100644 --- a/Android/app/src/main/cpp/CMakeLists.txt +++ b/Android/app/src/main/cpp/CMakeLists.txt @@ -9,15 +9,42 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/libs_export/${AND set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/libs_export/${ANDROID_ABI}/binary) set(OPENSSL_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/${ANDROID_ABI}") -#由于openssl库编译时未指定-fPIC,到时github action ci编译失败,先屏蔽掉 -#set(OPENSSL_INCLUDE_DIR "${OPENSSL_ROOT_DIR}/include") -#set(OPENSSL_CRYPTO_LIBRARY "${OPENSSL_ROOT_DIR}/libcrypto.a") -#set(OPENSSL_SSL_LIBRARY "${OPENSSL_ROOT_DIR}/libssl.a") + + +################################################################### +# 编译openssl 1.1.1k + +#if (ANDROID) +# message(WARNING "Enable Android openssl compile") +# execute_process( +# COMMAND bash -c "./../../3rdpart/openssl/Configure android-aarch64 -D__ANDROID_API__=16" +# OUTPUT_VARIABLE output +# RESULT_VARIABLE result +# ) +# if (result) +# message(FATAL_ERROR "Failed to execute bash command: ${result}") +# endif () +# message(WARNING "Enable Android openssl compile===================") +# message("Output: ${output}") +#ENDIF () #设置工程源码根目录 set(JNI_Root ${CMAKE_CURRENT_SOURCE_DIR}) set(ZLMediaKit_Root ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../) +#由于openssl库编译时未指定-fPIC,到时github action ci编译失败,先屏蔽掉 +set(OPENSSL_INCLUDE_DIR "${ZLMediaKit_Root}3rdpart/openssl/include") +set(OPENSSL_CRYPTO_LIBRARY "${ZLMediaKit_Root}Android/app/libs/${ANDROID_ABI}/libcrypto.a") +set(OPENSSL_SSL_LIBRARY "${ZLMediaKit_Root}Android/app/libs/${ANDROID_ABI}/libssl.a") + + + +set(SRTP_INCLUDE_DIRS "include") +set(SRTP_LIBRARIES "${ZLMediaKit_Root}Android/app/libs/${ANDROID_ABI}/libsrtp2.a") + +include_directories(${OPENSSL_INCLUDE_DIR}) +include_directories(${SRTP_INCLUDE_DIRS}) + #添加主工程cmake add_subdirectory(${ZLMediaKit_Root} ${EXECUTABLE_OUTPUT_PATH}) @@ -34,7 +61,7 @@ include_directories(${ZLMediaKit_Root}/3rdpart/ZLToolKit/src) #收集源代码添加动态库 file(GLOB JNI_src_list ${JNI_Root}/*.cpp ${JNI_Root}/*.h) add_library(zlmediakit_jni SHARED ${JNI_src_list}) - +message(WARNING ${MK_LINK_LIBRARIES}) #链接 target_link_libraries(zlmediakit_jni -Wl,--start-group log z ${MK_LINK_LIBRARIES} -Wl,--end-group) diff --git a/Android/app/src/main/cpp/include/srtp2/auth.h b/Android/app/src/main/cpp/include/srtp2/auth.h new file mode 100644 index 00000000..774ea168 --- /dev/null +++ b/Android/app/src/main/cpp/include/srtp2/auth.h @@ -0,0 +1,173 @@ +/* + * auth.h + * + * common interface to authentication functions + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2017, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef SRTP_AUTH_H +#define SRTP_AUTH_H + +#include "srtp.h" +#include "crypto_types.h" /* for values of auth_type_id_t */ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef const struct srtp_auth_type_t *srtp_auth_type_pointer; +typedef struct srtp_auth_t *srtp_auth_pointer_t; + +typedef srtp_err_status_t (*srtp_auth_alloc_func)(srtp_auth_pointer_t *ap, + int key_len, + int out_len); + +typedef srtp_err_status_t (*srtp_auth_init_func)(void *state, + const uint8_t *key, + int key_len); + +typedef srtp_err_status_t (*srtp_auth_dealloc_func)(srtp_auth_pointer_t ap); + +typedef srtp_err_status_t (*srtp_auth_compute_func)(void *state, + const uint8_t *buffer, + int octets_to_auth, + int tag_len, + uint8_t *tag); + +typedef srtp_err_status_t (*srtp_auth_update_func)(void *state, + const uint8_t *buffer, + int octets_to_auth); + +typedef srtp_err_status_t (*srtp_auth_start_func)(void *state); + +/* some syntactic sugar on these function types */ +#define srtp_auth_type_alloc(at, a, klen, outlen) \ + ((at)->alloc((a), (klen), (outlen))) + +#define srtp_auth_init(a, key) \ + (((a)->type)->init((a)->state, (key), ((a)->key_len))) + +#define srtp_auth_compute(a, buf, len, res) \ + (((a)->type)->compute((a)->state, (buf), (len), (a)->out_len, (res))) + +#define srtp_auth_update(a, buf, len) \ + (((a)->type)->update((a)->state, (buf), (len))) + +#define srtp_auth_start(a) (((a)->type)->start((a)->state)) + +#define srtp_auth_dealloc(c) (((c)->type)->dealloc(c)) + +/* functions to get information about a particular auth_t */ +int srtp_auth_get_key_length(const struct srtp_auth_t *a); + +int srtp_auth_get_tag_length(const struct srtp_auth_t *a); + +int srtp_auth_get_prefix_length(const struct srtp_auth_t *a); + +/* + * srtp_auth_test_case_t is a (list of) key/message/tag values that are + * known to be correct for a particular cipher. this data can be used + * to test an implementation in an on-the-fly self test of the + * correctness of the implementation. (see the srtp_auth_type_self_test() + * function below) + */ +typedef struct srtp_auth_test_case_t { + int key_length_octets; /* octets in key */ + const uint8_t *key; /* key */ + int data_length_octets; /* octets in data */ + const uint8_t *data; /* data */ + int tag_length_octets; /* octets in tag */ + const uint8_t *tag; /* tag */ + const struct srtp_auth_test_case_t + *next_test_case; /* pointer to next testcase */ +} srtp_auth_test_case_t; + +/* srtp_auth_type_t */ +typedef struct srtp_auth_type_t { + srtp_auth_alloc_func alloc; + srtp_auth_dealloc_func dealloc; + srtp_auth_init_func init; + srtp_auth_compute_func compute; + srtp_auth_update_func update; + srtp_auth_start_func start; + const char *description; + const srtp_auth_test_case_t *test_data; + srtp_auth_type_id_t id; +} srtp_auth_type_t; + +typedef struct srtp_auth_t { + const srtp_auth_type_t *type; + void *state; + int out_len; /* length of output tag in octets */ + int key_len; /* length of key in octets */ + int prefix_len; /* length of keystream prefix */ +} srtp_auth_t; + +/* + * srtp_auth_type_self_test() tests an auth_type against test cases + * provided in an array of values of key/message/tag that is known to + * be good + */ +srtp_err_status_t srtp_auth_type_self_test(const srtp_auth_type_t *at); + +/* + * srtp_auth_type_test() tests an auth_type against external test cases + * provided in an array of values of key/message/tag that is known to + * be good + */ +srtp_err_status_t srtp_auth_type_test(const srtp_auth_type_t *at, + const srtp_auth_test_case_t *test_data); + +/* + * srtp_replace_auth_type(ct, id) + * + * replaces srtp's kernel's auth type implementation for the auth_type id + * with a new one passed in externally. The new auth type must pass all the + * existing auth_type's self tests as well as its own. + */ +srtp_err_status_t srtp_replace_auth_type(const srtp_auth_type_t *ct, + srtp_auth_type_id_t id); + +#ifdef __cplusplus +} +#endif + +#endif /* SRTP_AUTH_H */ diff --git a/Android/app/src/main/cpp/include/srtp2/cipher.h b/Android/app/src/main/cpp/include/srtp2/cipher.h new file mode 100644 index 00000000..4f14e356 --- /dev/null +++ b/Android/app/src/main/cpp/include/srtp2/cipher.h @@ -0,0 +1,248 @@ +/* + * cipher.h + * + * common interface to ciphers + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2017 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef SRTP_CIPHER_H +#define SRTP_CIPHER_H + +#include "srtp.h" +#include "crypto_types.h" /* for values of cipher_type_id_t */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * srtp_cipher_direction_t defines a particular cipher operation. + * + * A srtp_cipher_direction_t is an enum that describes a particular cipher + * operation, i.e. encryption or decryption. For some ciphers, this + * distinction does not matter, but for others, it is essential. + */ +typedef enum { + srtp_direction_encrypt, /**< encryption (convert plaintext to ciphertext) */ + srtp_direction_decrypt, /**< decryption (convert ciphertext to plaintext) */ + srtp_direction_any /**< encryption or decryption */ +} srtp_cipher_direction_t; + +/* + * the srtp_cipher_pointer_t definition is needed + * as srtp_cipher_t is not yet defined + */ +typedef struct srtp_cipher_t *srtp_cipher_pointer_t; + +/* + * a srtp_cipher_alloc_func_t allocates (but does not initialize) a + * srtp_cipher_t + */ +typedef srtp_err_status_t (*srtp_cipher_alloc_func_t)(srtp_cipher_pointer_t *cp, + int key_len, + int tag_len); + +/* + * a srtp_cipher_init_func_t [re-]initializes a cipher_t with a given key + */ +typedef srtp_err_status_t (*srtp_cipher_init_func_t)(void *state, + const uint8_t *key); + +/* a srtp_cipher_dealloc_func_t de-allocates a cipher_t */ +typedef srtp_err_status_t (*srtp_cipher_dealloc_func_t)( + srtp_cipher_pointer_t cp); + +/* + * a srtp_cipher_set_aad_func_t processes the AAD data for AEAD ciphers + */ +typedef srtp_err_status_t (*srtp_cipher_set_aad_func_t)(void *state, + const uint8_t *aad, + uint32_t aad_len); + +/* a srtp_cipher_encrypt_func_t encrypts data in-place */ +typedef srtp_err_status_t (*srtp_cipher_encrypt_func_t)( + void *state, + uint8_t *buffer, + unsigned int *octets_to_encrypt); + +/* a srtp_cipher_decrypt_func_t decrypts data in-place */ +typedef srtp_err_status_t (*srtp_cipher_decrypt_func_t)( + void *state, + uint8_t *buffer, + unsigned int *octets_to_decrypt); + +/* + * a srtp_cipher_set_iv_func_t function sets the current initialization vector + */ +typedef srtp_err_status_t (*srtp_cipher_set_iv_func_t)( + void *state, + uint8_t *iv, + srtp_cipher_direction_t direction); + +/* + * a cipher_get_tag_func_t function is used to get the authentication + * tag that was calculated by an AEAD cipher. + */ +typedef srtp_err_status_t (*srtp_cipher_get_tag_func_t)(void *state, + uint8_t *tag, + uint32_t *len); + +/* + * srtp_cipher_test_case_t is a (list of) key, salt, plaintext, ciphertext, + * and aad values that are known to be correct for a + * particular cipher. this data can be used to test an implementation + * in an on-the-fly self test of the correctness of the implementation. + * (see the srtp_cipher_type_self_test() function below) + */ +typedef struct srtp_cipher_test_case_t { + int key_length_octets; /* octets in key */ + const uint8_t *key; /* key */ + uint8_t *idx; /* packet index */ + unsigned int plaintext_length_octets; /* octets in plaintext */ + const uint8_t *plaintext; /* plaintext */ + unsigned int ciphertext_length_octets; /* octets in plaintext */ + const uint8_t *ciphertext; /* ciphertext */ + int aad_length_octets; /* octets in AAD */ + const uint8_t *aad; /* AAD */ + int tag_length_octets; /* Length of AEAD tag */ + const struct srtp_cipher_test_case_t + *next_test_case; /* pointer to next testcase */ +} srtp_cipher_test_case_t; + +/* srtp_cipher_type_t defines the 'metadata' for a particular cipher type */ +typedef struct srtp_cipher_type_t { + srtp_cipher_alloc_func_t alloc; + srtp_cipher_dealloc_func_t dealloc; + srtp_cipher_init_func_t init; + srtp_cipher_set_aad_func_t set_aad; + srtp_cipher_encrypt_func_t encrypt; + srtp_cipher_encrypt_func_t decrypt; + srtp_cipher_set_iv_func_t set_iv; + srtp_cipher_get_tag_func_t get_tag; + const char *description; + const srtp_cipher_test_case_t *test_data; + srtp_cipher_type_id_t id; +} srtp_cipher_type_t; + +/* + * srtp_cipher_t defines an instantiation of a particular cipher, with fixed + * key length, key and salt values + */ +typedef struct srtp_cipher_t { + const srtp_cipher_type_t *type; + void *state; + int key_len; + int algorithm; +} srtp_cipher_t; + +/* some bookkeeping functions */ +int srtp_cipher_get_key_length(const srtp_cipher_t *c); + +/* + * srtp_cipher_type_self_test() tests a cipher against test cases provided in + * an array of values of key/srtp_xtd_seq_num_t/plaintext/ciphertext + * that is known to be good + */ +srtp_err_status_t srtp_cipher_type_self_test(const srtp_cipher_type_t *ct); + +/* + * srtp_cipher_type_test() tests a cipher against external test cases provided + * in + * an array of values of key/srtp_xtd_seq_num_t/plaintext/ciphertext + * that is known to be good + */ +srtp_err_status_t srtp_cipher_type_test( + const srtp_cipher_type_t *ct, + const srtp_cipher_test_case_t *test_data); + +/* + * srtp_cipher_bits_per_second(c, l, t) computes (an estimate of) the + * number of bits that a cipher implementation can encrypt in a second + * + * c is a cipher (which MUST be allocated and initialized already), l + * is the length in octets of the test data to be encrypted, and t is + * the number of trials + * + * if an error is encountered, then the value 0 is returned + */ +uint64_t srtp_cipher_bits_per_second(srtp_cipher_t *c, + int octets_in_buffer, + int num_trials); + +srtp_err_status_t srtp_cipher_type_alloc(const srtp_cipher_type_t *ct, + srtp_cipher_t **c, + int key_len, + int tlen); +srtp_err_status_t srtp_cipher_dealloc(srtp_cipher_t *c); +srtp_err_status_t srtp_cipher_init(srtp_cipher_t *c, const uint8_t *key); +srtp_err_status_t srtp_cipher_set_iv(srtp_cipher_t *c, + uint8_t *iv, + int direction); +srtp_err_status_t srtp_cipher_output(srtp_cipher_t *c, + uint8_t *buffer, + uint32_t *num_octets_to_output); +srtp_err_status_t srtp_cipher_encrypt(srtp_cipher_t *c, + uint8_t *buffer, + uint32_t *num_octets_to_output); +srtp_err_status_t srtp_cipher_decrypt(srtp_cipher_t *c, + uint8_t *buffer, + uint32_t *num_octets_to_output); +srtp_err_status_t srtp_cipher_get_tag(srtp_cipher_t *c, + uint8_t *buffer, + uint32_t *tag_len); +srtp_err_status_t srtp_cipher_set_aad(srtp_cipher_t *c, + const uint8_t *aad, + uint32_t aad_len); + +/* + * srtp_replace_cipher_type(ct, id) + * + * replaces srtp's existing cipher implementation for the cipher_type id + * with a new one passed in externally. The new cipher must pass all the + * existing cipher_type's self tests as well as its own. + */ +srtp_err_status_t srtp_replace_cipher_type(const srtp_cipher_type_t *ct, + srtp_cipher_type_id_t id); + +#ifdef __cplusplus +} +#endif + +#endif /* SRTP_CIPHER_H */ diff --git a/Android/app/src/main/cpp/include/srtp2/crypto_types.h b/Android/app/src/main/cpp/include/srtp2/crypto_types.h new file mode 100644 index 00000000..7fd3178b --- /dev/null +++ b/Android/app/src/main/cpp/include/srtp2/crypto_types.h @@ -0,0 +1,116 @@ +/* + * crypto_types.h + * + * constants for cipher types and auth func types + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright(c) 2001-2017 Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef SRTP_CRYPTO_TYPES_H +#define SRTP_CRYPTO_TYPES_H + +/* + * The null cipher performs no encryption. + * + * The SRTP_NULL_CIPHER leaves its inputs unaltered, during both the + * encryption and decryption operations. This cipher can be chosen + * to indicate that no encryption is to be performed. + */ +#define SRTP_NULL_CIPHER 0 + +/* + * AES-128 Integer Counter Mode (AES ICM) + * + * AES-128 ICM is the variant of counter mode that is used by + * Secure RTP. This cipher uses a 16-octet key concatenated with a + * 14-octet offset (or salt) value. + */ +#define SRTP_AES_ICM_128 1 + +/* + * AES-192 Integer Counter Mode (AES ICM) + * + * AES-128 ICM is the variant of counter mode that is used by + * Secure RTP. This cipher uses a 24-octet key concatenated with a + * 14-octet offset (or salt) value. + */ +#define SRTP_AES_ICM_192 4 + +/* + * AES-256 Integer Counter Mode (AES ICM) + * + * AES-128 ICM is the variant of counter mode that is used by + * Secure RTP. This cipher uses a 32-octet key concatenated with a + * 14-octet offset (or salt) value. + */ +#define SRTP_AES_ICM_256 5 + +/* + * AES-128_GCM Galois Counter Mode (AES GCM) + * + * AES-128 GCM is the variant of galois counter mode that is used by + * Secure RTP. This cipher uses a 16-octet key. + */ +#define SRTP_AES_GCM_128 6 + +/* + * AES-256_GCM Galois Counter Mode (AES GCM) + * + * AES-256 GCM is the variant of galois counter mode that is used by + * Secure RTP. This cipher uses a 32-octet key. + */ +#define SRTP_AES_GCM_256 7 + +/* + * The null authentication function performs no authentication. + * + * The NULL_AUTH function does nothing, and can be selected to indicate + * that authentication should not be performed. + */ +#define SRTP_NULL_AUTH 0 + +/* + * HMAC-SHA1 + * + * SRTP_HMAC_SHA1 implements the Hash-based MAC using the NIST Secure + * Hash Algorithm version 1 (SHA1). + */ +#define SRTP_HMAC_SHA1 3 + +#endif /* SRTP_CRYPTO_TYPES_H */ diff --git a/Android/app/src/main/cpp/include/srtp2/srtp.h b/Android/app/src/main/cpp/include/srtp2/srtp.h new file mode 100644 index 00000000..fa34daf6 --- /dev/null +++ b/Android/app/src/main/cpp/include/srtp2/srtp.h @@ -0,0 +1,1747 @@ +/* + * srtp.h + * + * interface to libsrtp + * + * David A. McGrew + * Cisco Systems, Inc. + */ +/* + * + * Copyright (c) 2001-2017, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef SRTP_SRTP_H +#define SRTP_SRTP_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup SRTP Secure RTP + * + * @brief libSRTP provides functions for protecting RTP and RTCP. See + * Section @ref Overview for an introduction to the use of the library. + * + * @{ + */ + +/* + * SRTP_MASTER_KEY_LEN is the nominal master key length supported by libSRTP + */ + +#define SRTP_MASTER_KEY_LEN 30 + +/* + * SRTP_MAX_KEY_LEN is the maximum key length supported by libSRTP + */ +#define SRTP_MAX_KEY_LEN 64 + +/* + * SRTP_MAX_TAG_LEN is the maximum tag length supported by libSRTP + */ + +#define SRTP_MAX_TAG_LEN 16 + +/** + * SRTP_MAX_MKI_LEN is the maximum size the MKI could be which is + * 128 bytes + */ +#define SRTP_MAX_MKI_LEN 128 + +/** + * SRTP_MAX_TRAILER_LEN is the maximum length of the SRTP trailer + * (authentication tag and MKI) supported by libSRTP. This value is + * the maximum number of octets that will be added to an RTP packet by + * srtp_protect(). + * + * @brief the maximum number of octets added by srtp_protect(). + */ +#define SRTP_MAX_TRAILER_LEN (SRTP_MAX_TAG_LEN + SRTP_MAX_MKI_LEN) + +/** + * SRTP_MAX_NUM_MASTER_KEYS is the maximum number of Master keys for + * MKI supported by libSRTP. + * + */ +#define SRTP_MAX_NUM_MASTER_KEYS 16 + +#define SRTP_SALT_LEN 14 + +/* + * SRTP_AEAD_SALT_LEN is the length of the SALT values used with + * GCM mode. GCM mode requires an IV. The SALT value is used + * as part of the IV formation logic applied to each RTP packet. + */ +#define SRTP_AEAD_SALT_LEN 12 + +#define SRTP_AES_128_KEY_LEN 16 +#define SRTP_AES_192_KEY_LEN 24 +#define SRTP_AES_256_KEY_LEN 32 + +#define SRTP_AES_ICM_128_KEY_LEN_WSALT (SRTP_SALT_LEN + SRTP_AES_128_KEY_LEN) +#define SRTP_AES_ICM_192_KEY_LEN_WSALT (SRTP_SALT_LEN + SRTP_AES_192_KEY_LEN) +#define SRTP_AES_ICM_256_KEY_LEN_WSALT (SRTP_SALT_LEN + SRTP_AES_256_KEY_LEN) + +#define SRTP_AES_GCM_128_KEY_LEN_WSALT \ + (SRTP_AEAD_SALT_LEN + SRTP_AES_128_KEY_LEN) +#define SRTP_AES_GCM_192_KEY_LEN_WSALT \ + (SRTP_AEAD_SALT_LEN + SRTP_AES_192_KEY_LEN) +#define SRTP_AES_GCM_256_KEY_LEN_WSALT \ + (SRTP_AEAD_SALT_LEN + SRTP_AES_256_KEY_LEN) + +/** + * @brief A srtp_cipher_type_id_t is an identifier for a particular cipher + * type. + * + * A srtp_cipher_type_id_t is an integer that represents a particular + * cipher type, e.g. the Advanced Encryption Standard (AES). A + * SRTP_NULL_CIPHER is available; this cipher leaves the data unchanged, + * and can be selected to indicate that no encryption is to take + * place. + * + * @ingroup Ciphers + */ +typedef uint32_t srtp_cipher_type_id_t; + +/** + * @brief An srtp_auth_type_id_t is an identifier for a particular + * authentication + * function. + * + * An srtp_auth_type_id_t is an integer that represents a particular + * authentication function type, e.g. HMAC-SHA1. A SRTP_NULL_AUTH is + * available; this authentication function performs no computation, + * and can be selected to indicate that no authentication is to take + * place. + * + * @ingroup Authentication + */ +typedef uint32_t srtp_auth_type_id_t; + +/** + * @brief srtp_err_status_t defines error codes. + * + * The enumeration srtp_err_status_t defines error codes. Note that the + * value of srtp_err_status_ok is equal to zero, which can simplify error + * checking somewhat. + * + */ +typedef enum { + srtp_err_status_ok = 0, /**< nothing to report */ + srtp_err_status_fail = 1, /**< unspecified failure */ + srtp_err_status_bad_param = 2, /**< unsupported parameter */ + srtp_err_status_alloc_fail = 3, /**< couldn't allocate memory */ + srtp_err_status_dealloc_fail = 4, /**< couldn't deallocate properly */ + srtp_err_status_init_fail = 5, /**< couldn't initialize */ + srtp_err_status_terminus = 6, /**< can't process as much data as */ + /**< requested */ + srtp_err_status_auth_fail = 7, /**< authentication failure */ + srtp_err_status_cipher_fail = 8, /**< cipher failure */ + srtp_err_status_replay_fail = 9, /**< replay check failed (bad index) */ + srtp_err_status_replay_old = 10, /**< replay check failed (index too */ + /**< old) */ + srtp_err_status_algo_fail = 11, /**< algorithm failed test routine */ + srtp_err_status_no_such_op = 12, /**< unsupported operation */ + srtp_err_status_no_ctx = 13, /**< no appropriate context found */ + srtp_err_status_cant_check = 14, /**< unable to perform desired */ + /**< validation */ + srtp_err_status_key_expired = 15, /**< can't use key any more */ + srtp_err_status_socket_err = 16, /**< error in use of socket */ + srtp_err_status_signal_err = 17, /**< error in use POSIX signals */ + srtp_err_status_nonce_bad = 18, /**< nonce check failed */ + srtp_err_status_read_fail = 19, /**< couldn't read data */ + srtp_err_status_write_fail = 20, /**< couldn't write data */ + srtp_err_status_parse_err = 21, /**< error parsing data */ + srtp_err_status_encode_err = 22, /**< error encoding data */ + srtp_err_status_semaphore_err = 23, /**< error while using semaphores */ + srtp_err_status_pfkey_err = 24, /**< error while using pfkey */ + srtp_err_status_bad_mki = 25, /**< error MKI present in packet is */ + /**< invalid */ + srtp_err_status_pkt_idx_old = 26, /**< packet index is too old to */ + /**< consider */ + srtp_err_status_pkt_idx_adv = 27 /**< packet index advanced, reset */ + /**< needed */ +} srtp_err_status_t; + +typedef struct srtp_ctx_t_ srtp_ctx_t; + +/** + * @brief srtp_sec_serv_t describes a set of security services. + * + * A srtp_sec_serv_t enumeration is used to describe the particular + * security services that will be applied by a particular crypto + * policy (or other mechanism). + */ +typedef enum { + sec_serv_none = 0, /**< no services */ + sec_serv_conf = 1, /**< confidentiality */ + sec_serv_auth = 2, /**< authentication */ + sec_serv_conf_and_auth = 3 /**< confidentiality and authentication */ +} srtp_sec_serv_t; + +/** + * @brief srtp_crypto_policy_t describes a particular crypto policy that + * can be applied to an SRTP stream. + * + * A srtp_crypto_policy_t describes a particular cryptographic policy that + * can be applied to an SRTP or SRTCP stream. An SRTP session policy + * consists of a list of these policies, one for each SRTP stream + * in the session. + */ +typedef struct srtp_crypto_policy_t { + srtp_cipher_type_id_t cipher_type; /**< An integer representing */ + /**< the type of cipher. */ + int cipher_key_len; /**< The length of the cipher key */ + /**< in octets. */ + srtp_auth_type_id_t auth_type; /**< An integer representing the */ + /**< authentication function. */ + int auth_key_len; /**< The length of the authentication */ + /**< function key in octets. */ + int auth_tag_len; /**< The length of the authentication */ + /**< tag in octets. */ + srtp_sec_serv_t sec_serv; /**< The flag indicating the security */ + /**< services to be applied. */ +} srtp_crypto_policy_t; + +/** + * @brief srtp_ssrc_type_t describes the type of an SSRC. + * + * An srtp_ssrc_type_t enumeration is used to indicate a type of SSRC. See + * @ref srtp_policy_t for more information. + */ +typedef enum { + ssrc_undefined = 0, /**< Indicates an undefined SSRC type. */ + ssrc_specific = 1, /**< Indicates a specific SSRC value */ + ssrc_any_inbound = 2, /**< Indicates any inbound SSRC value */ + /**< (i.e. a value that is used in the */ + /**< function srtp_unprotect()) */ + ssrc_any_outbound = 3 /**< Indicates any outbound SSRC value */ + /**< (i.e. a value that is used in the */ + /**< function srtp_protect()) */ +} srtp_ssrc_type_t; + +/** + * @brief An srtp_ssrc_t represents a particular SSRC value, or a `wildcard' + * SSRC. + * + * An srtp_ssrc_t represents a particular SSRC value (if its type is + * ssrc_specific), or a wildcard SSRC value that will match all + * outbound SSRCs (if its type is ssrc_any_outbound) or all inbound + * SSRCs (if its type is ssrc_any_inbound). + */ +typedef struct { + srtp_ssrc_type_t type; /**< The type of this particular SSRC */ + unsigned int value; /**< The value of this SSRC, if it is not a */ + /**< wildcard */ +} srtp_ssrc_t; + +/** + * @brief srtp_master_key_t represents a master key. There will + * be a Master Key Index and the Master Key associated with the + * Master Key Index. Need to also keep track of the Master Key + * Index Size to correctly read it from a packet. + */ +typedef struct srtp_master_key_t { + unsigned char *key; + unsigned char *mki_id; + unsigned int mki_size; +} srtp_master_key_t; + +/** + * @brief represents the policy for an SRTP session. + * + * A single srtp_policy_t struct represents the policy for a single + * SRTP stream, and a linked list of these elements represents the + * policy for an entire SRTP session. Each element contains the SRTP + * and SRTCP crypto policies for that stream, a pointer to the SRTP + * master key for that stream, the SSRC describing that stream, or a + * flag indicating a `wildcard' SSRC value, and a `next' field that + * holds a pointer to the next element in the list of policy elements, + * or NULL if it is the last element. + * + * The wildcard value SSRC_ANY_INBOUND matches any SSRC from an + * inbound stream that for which there is no explicit SSRC entry in + * another policy element. Similarly, the value SSRC_ANY_OUTBOUND + * will matches any SSRC from an outbound stream that does not appear + * in another policy element. Note that wildcard SSRCs &b cannot be + * used to match both inbound and outbound traffic. This restriction + * is intentional, and it allows libSRTP to ensure that no security + * lapses result from accidental re-use of SSRC values during key + * sharing. + * + * @warning The final element of the list @b must have its `next' pointer + * set to NULL. + */ + +typedef struct srtp_policy_t { + srtp_ssrc_t ssrc; /**< The SSRC value of stream, or the */ + /**< flags SSRC_ANY_INBOUND or */ + /**< SSRC_ANY_OUTBOUND if key sharing */ + /**< is used for this policy element. */ + srtp_crypto_policy_t rtp; /**< SRTP crypto policy. */ + srtp_crypto_policy_t rtcp; /**< SRTCP crypto policy. */ + unsigned char *key; /**< Pointer to the SRTP master key for */ + /**< this stream. */ + srtp_master_key_t **keys; /** Array of Master Key structures */ + unsigned long num_master_keys; /** Number of master keys */ + void *deprecated_ekt; /**< DEPRECATED: pointer to the EKT */ + /**< policy structure for this stream */ + unsigned long window_size; /**< The window size to use for replay */ + /**< protection. */ + int allow_repeat_tx; /**< Whether retransmissions of */ + /**< packets with the same sequence */ + /**< number are allowed. */ + /**< (Note that such repeated */ + /**< transmissions must have the same */ + /**< RTP payload, or a severe security */ + /**< weakness is introduced!) */ + int *enc_xtn_hdr; /**< List of header ids to encrypt. */ + int enc_xtn_hdr_count; /**< Number of entries in list of header */ + /**< ids. */ + struct srtp_policy_t *next; /**< Pointer to next stream policy. */ +} srtp_policy_t; + +/** + * @brief An srtp_t points to an SRTP session structure. + * + * The typedef srtp_t is a pointer to a structure that represents + * an SRTP session. This datatype is intentionally opaque in + * order to separate the interface from the implementation. + * + * An SRTP session consists of all of the traffic sent to the RTP and + * RTCP destination transport addresses, using the RTP/SAVP (Secure + * Audio/Video Profile). A session can be viewed as a set of SRTP + * streams, each of which originates with a different participant. + */ +typedef srtp_ctx_t *srtp_t; + +/** + * @brief srtp_init() initializes the srtp library. + * + * @warning This function @b must be called before any other srtp + * functions. + */ +srtp_err_status_t srtp_init(void); + +/** + * @brief srtp_shutdown() de-initializes the srtp library. + * + * @warning No srtp functions may be called after calling this function. + */ +srtp_err_status_t srtp_shutdown(void); + +/** + * @brief srtp_protect() is the Secure RTP sender-side packet processing + * function. + * + * The function call srtp_protect(ctx, rtp_hdr, len_ptr) applies SRTP + * protection to the RTP packet rtp_hdr (which has length *len_ptr) using + * the SRTP context ctx. If srtp_err_status_ok is returned, then rtp_hdr + * points to the resulting SRTP packet and *len_ptr is the number of + * octets in that packet; otherwise, no assumptions should be made + * about the value of either data elements. + * + * The sequence numbers of the RTP packets presented to this function + * need not be consecutive, but they @b must be out of order by less + * than 2^15 = 32,768 packets. + * + * @warning This function assumes that it can write the authentication + * tag into the location in memory immediately following the RTP + * packet, and assumes that the RTP packet is aligned on a 32-bit + * boundary. + * + * @warning This function assumes that it can write SRTP_MAX_TRAILER_LEN + * into the location in memory immediately following the RTP packet. + * Callers MUST ensure that this much writable memory is available in + * the buffer that holds the RTP packet. + * + * @param ctx is the SRTP context to use in processing the packet. + * + * @param rtp_hdr is a pointer to the RTP packet (before the call); after + * the function returns, it points to the srtp packet. + * + * @param len_ptr is a pointer to the length in octets of the complete + * RTP packet (header and body) before the function call, and of the + * complete SRTP packet after the call, if srtp_err_status_ok was returned. + * Otherwise, the value of the data to which it points is undefined. + * + * @return + * - srtp_err_status_ok no problems + * - srtp_err_status_replay_fail rtp sequence number was non-increasing + * - @e other failure in cryptographic mechanisms + */ +srtp_err_status_t srtp_protect(srtp_t ctx, void *rtp_hdr, int *len_ptr); + +/** + * @brief srtp_protect_mki() is the Secure RTP sender-side packet processing + * function that can utilize MKI. + * + * The function call srtp_protect(ctx, rtp_hdr, len_ptr) applies SRTP + * protection to the RTP packet rtp_hdr (which has length *len_ptr) using + * the SRTP context ctx. If srtp_err_status_ok is returned, then rtp_hdr + * points to the resulting SRTP packet and *len_ptr is the number of + * octets in that packet; otherwise, no assumptions should be made + * about the value of either data elements. + * + * The sequence numbers of the RTP packets presented to this function + * need not be consecutive, but they @b must be out of order by less + * than 2^15 = 32,768 packets. + * + * @warning This function assumes that it can write the authentication + * tag into the location in memory immediately following the RTP + * packet, and assumes that the RTP packet is aligned on a 32-bit + * boundary. + * + * @warning This function assumes that it can write SRTP_MAX_TRAILER_LEN + * into the location in memory immediately following the RTP packet. + * Callers MUST ensure that this much writable memory is available in + * the buffer that holds the RTP packet. + * + * @param ctx is the SRTP context to use in processing the packet. + * + * @param rtp_hdr is a pointer to the RTP packet (before the call); after + * the function returns, it points to the srtp packet. + * + * @param pkt_octet_len is a pointer to the length in octets of the complete + * RTP packet (header and body) before the function call, and of the + * complete SRTP packet after the call, if srtp_err_status_ok was returned. + * Otherwise, the value of the data to which it points is undefined. + * + * @param use_mki is a boolean to tell the system if mki is being used. If + * set to false then will use the first set of session keys. If set to true + * will + * use the session keys identified by the mki_index + * + * @param mki_index integer value specifying which set of session keys should be + * used if use_mki is set to true. + * + * @return + * - srtp_err_status_ok no problems + * - srtp_err_status_replay_fail rtp sequence number was non-increasing + * - @e other failure in cryptographic mechanisms + */ +srtp_err_status_t srtp_protect_mki(srtp_ctx_t *ctx, + void *rtp_hdr, + int *pkt_octet_len, + unsigned int use_mki, + unsigned int mki_index); + +/** + * @brief srtp_unprotect() is the Secure RTP receiver-side packet + * processing function. + * + * The function call srtp_unprotect(ctx, srtp_hdr, len_ptr) verifies + * the Secure RTP protection of the SRTP packet pointed to by srtp_hdr + * (which has length *len_ptr), using the SRTP context ctx. If + * srtp_err_status_ok is returned, then srtp_hdr points to the resulting + * RTP packet and *len_ptr is the number of octets in that packet; + * otherwise, no assumptions should be made about the value of either + * data elements. + * + * The sequence numbers of the RTP packets presented to this function + * need not be consecutive, but they @b must be out of order by less + * than 2^15 = 32,768 packets. + * + * @warning This function assumes that the SRTP packet is aligned on a + * 32-bit boundary. + * + * @param ctx is the SRTP session which applies to the particular packet. + * + * @param srtp_hdr is a pointer to the header of the SRTP packet + * (before the call). after the function returns, it points to the + * rtp packet if srtp_err_status_ok was returned; otherwise, the value of + * the data to which it points is undefined. + * + * @param len_ptr is a pointer to the length in octets of the complete + * srtp packet (header and body) before the function call, and of the + * complete rtp packet after the call, if srtp_err_status_ok was returned. + * Otherwise, the value of the data to which it points is undefined. + * + * @return + * - srtp_err_status_ok if the RTP packet is valid. + * - srtp_err_status_auth_fail if the SRTP packet failed the message + * authentication check. + * - srtp_err_status_replay_fail if the SRTP packet is a replay (e.g. packet + * has already been processed and accepted). + * - [other] if there has been an error in the cryptographic mechanisms. + * + */ +srtp_err_status_t srtp_unprotect(srtp_t ctx, void *srtp_hdr, int *len_ptr); + +/** + * @brief srtp_unprotect_mki() is the Secure RTP receiver-side packet + * processing function that checks for MKI. + * + * The function call srtp_unprotect(ctx, srtp_hdr, len_ptr) verifies + * the Secure RTP protection of the SRTP packet pointed to by srtp_hdr + * (which has length *len_ptr), using the SRTP context ctx. If + * srtp_err_status_ok is returned, then srtp_hdr points to the resulting + * RTP packet and *len_ptr is the number of octets in that packet; + * otherwise, no assumptions should be made about the value of either + * data elements. + * + * The sequence numbers of the RTP packets presented to this function + * need not be consecutive, but they @b must be out of order by less + * than 2^15 = 32,768 packets. + * + * @warning This function assumes that the SRTP packet is aligned on a + * 32-bit boundary. + * + * @param ctx is the SRTP session which applies to the particular packet. + * + * @param srtp_hdr is a pointer to the header of the SRTP packet + * (before the call). after the function returns, it points to the + * rtp packet if srtp_err_status_ok was returned; otherwise, the value of + * the data to which it points is undefined. + * + * @param len_ptr is a pointer to the length in octets of the complete + * srtp packet (header and body) before the function call, and of the + * complete rtp packet after the call, if srtp_err_status_ok was returned. + * Otherwise, the value of the data to which it points is undefined. + * + * @param use_mki is a boolean to tell the system if mki is being used. If + * set to false then will use the first set of session keys. If set to true + * will + * use the session keys identified by the mki_index + * + * @return + * - srtp_err_status_ok if the RTP packet is valid. + * - srtp_err_status_auth_fail if the SRTP packet failed the message + * authentication check. + * - srtp_err_status_replay_fail if the SRTP packet is a replay (e.g. packet + * has already been processed and accepted). + * - srtp_err_status_bad_mki if the MKI in the packet is not a known MKI id + * - [other] if there has been an error in the cryptographic mechanisms. + * + */ +srtp_err_status_t srtp_unprotect_mki(srtp_t ctx, + void *srtp_hdr, + int *len_ptr, + unsigned int use_mki); + +/** + * @brief srtp_create() allocates and initializes an SRTP session. + + * The function call srtp_create(session, policy) allocates and + * initializes an SRTP session context, applying the given policy. + * + * @param session is a pointer to the SRTP session to which the policy is + * to be added. + * + * @param policy is the srtp_policy_t struct that describes the policy + * for the session. The struct may be a single element, or it may be + * the head of a list, in which case each element of the list is + * processed. It may also be NULL, in which case streams should be added + * later using srtp_add_stream(). The final element of the list @b must + * have its `next' field set to NULL. + * + * @return + * - srtp_err_status_ok if creation succeeded. + * - srtp_err_status_alloc_fail if allocation failed. + * - srtp_err_status_init_fail if initialization failed. + */ +srtp_err_status_t srtp_create(srtp_t *session, const srtp_policy_t *policy); + +/** + * @brief srtp_add_stream() allocates and initializes an SRTP stream + * within a given SRTP session. + * + * The function call srtp_add_stream(session, policy) allocates and + * initializes a new SRTP stream within a given, previously created + * session, applying the policy given as the other argument to that + * stream. + * + * @return values: + * - srtp_err_status_ok if stream creation succeeded. + * - srtp_err_status_alloc_fail if stream allocation failed + * - srtp_err_status_init_fail if stream initialization failed. + */ +srtp_err_status_t srtp_add_stream(srtp_t session, const srtp_policy_t *policy); + +/** + * @brief srtp_remove_stream() deallocates an SRTP stream. + * + * The function call srtp_remove_stream(session, ssrc) removes + * the SRTP stream with the SSRC value ssrc from the SRTP session + * context given by the argument session. + * + * @param session is the SRTP session from which the stream + * will be removed. + * + * @param ssrc is the SSRC value of the stream to be removed + * in network byte order. + * + * @warning Wildcard SSRC values cannot be removed from a + * session. + * + * @return + * - srtp_err_status_ok if the stream deallocation succeeded. + * - [other] otherwise. + * + */ +srtp_err_status_t srtp_remove_stream(srtp_t session, unsigned int ssrc); + +/** + * @brief srtp_update() updates all streams in the session. + * + * The function call srtp_update(session, policy) updates + * all the streams in the session applying the given policy + * and key. The existing ROC value of all streams will be + * preserved. + * + * @param session is the SRTP session that contains the streams + * to be updated. + * + * @param policy is the srtp_policy_t struct that describes the policy + * for the session. The struct may be a single element, or it may be + * the head of a list, in which case each element of the list is + * processed. The final element of the list @b must + * have its `next' field set to NULL. + * + * @return + * - srtp_err_status_ok if stream creation succeed. + * - srtp_err_status_alloc_fail if stream allocation failed + * - srtp_err_status_init_fail if stream initialization failed. + * - [other] otherwise. + * + */ +srtp_err_status_t srtp_update(srtp_t session, const srtp_policy_t *policy); + +/** + * @brief srtp_update_stream() updates a SRTP stream. + * + * The function call srtp_update_stream(session, policy) updates + * the stream(s) in the session that match applying the given + * policy and key. The existing ROC value of all stream(s) will + * be preserved. + * + * @param session is the SRTP session that contains the streams + * to be updated. + * + * @param policy is the srtp_policy_t struct that describes the policy + * for the session. + * + * @return + * - srtp_err_status_ok if stream creation succeeded. + * - srtp_err_status_alloc_fail if stream allocation failed + * - srtp_err_status_init_fail if stream initialization failed. + * - [other] otherwise. + * + */ +srtp_err_status_t srtp_update_stream(srtp_t session, + const srtp_policy_t *policy); + +/** + * @brief srtp_crypto_policy_set_rtp_default() sets a crypto policy + * structure to the SRTP default policy for RTP protection. + * + * @param p is a pointer to the policy structure to be set + * + * The function call srtp_crypto_policy_set_rtp_default(&p) sets the + * srtp_crypto_policy_t at location p to the SRTP default policy for RTP + * protection, as defined in the specification. This function is a + * convenience that helps to avoid dealing directly with the policy + * data structure. You are encouraged to initialize policy elements + * with this function call. Doing so may allow your code to be + * forward compatible with later versions of libSRTP that include more + * elements in the srtp_crypto_policy_t datatype. + * + * @return void. + * + */ +void srtp_crypto_policy_set_rtp_default(srtp_crypto_policy_t *p); + +/** + * @brief srtp_crypto_policy_set_rtcp_default() sets a crypto policy + * structure to the SRTP default policy for RTCP protection. + * + * @param p is a pointer to the policy structure to be set + * + * The function call srtp_crypto_policy_set_rtcp_default(&p) sets the + * srtp_crypto_policy_t at location p to the SRTP default policy for RTCP + * protection, as defined in the specification. This function is a + * convenience that helps to avoid dealing directly with the policy + * data structure. You are encouraged to initialize policy elements + * with this function call. Doing so may allow your code to be + * forward compatible with later versions of libSRTP that include more + * elements in the srtp_crypto_policy_t datatype. + * + * @return void. + * + */ +void srtp_crypto_policy_set_rtcp_default(srtp_crypto_policy_t *p); + +/** + * @brief srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80() sets a crypto + * policy structure to the SRTP default policy for RTP protection. + * + * @param p is a pointer to the policy structure to be set + * + * The function srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80() is a + * synonym for srtp_crypto_policy_set_rtp_default(). It conforms to the + * naming convention used in RFC 4568 (SDP Security Descriptions for + * Media Streams). + * + * @return void. + * + */ +#define srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(p) \ + srtp_crypto_policy_set_rtp_default(p) + +/** + * @brief srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32() sets a crypto + * policy structure to a short-authentication tag policy + * + * @param p is a pointer to the policy structure to be set + * + * The function call srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32(&p) + * sets the srtp_crypto_policy_t at location p to use policy + * AES_CM_128_HMAC_SHA1_32 as defined in RFC 4568. + * This policy uses AES-128 + * Counter Mode encryption and HMAC-SHA1 authentication, with an + * authentication tag that is only 32 bits long. This length is + * considered adequate only for protecting audio and video media that + * use a stateless playback function. See Section 7.5 of RFC 3711 + * (http://www.ietf.org/rfc/rfc3711.txt). + * + * This function is a convenience that helps to avoid dealing directly + * with the policy data structure. You are encouraged to initialize + * policy elements with this function call. Doing so may allow your + * code to be forward compatible with later versions of libSRTP that + * include more elements in the srtp_crypto_policy_t datatype. + * + * @warning This crypto policy is intended for use in SRTP, but not in + * SRTCP. It is recommended that a policy that uses longer + * authentication tags be used for SRTCP. See Section 7.5 of RFC 3711 + * (http://www.ietf.org/rfc/rfc3711.txt). + * + * @return void. + * + */ +void srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32(srtp_crypto_policy_t *p); + +/** + * @brief srtp_crypto_policy_set_aes_cm_128_null_auth() sets a crypto + * policy structure to an encryption-only policy + * + * @param p is a pointer to the policy structure to be set + * + * The function call srtp_crypto_policy_set_aes_cm_128_null_auth(&p) sets + * the srtp_crypto_policy_t at location p to use the SRTP default cipher + * (AES-128 Counter Mode), but to use no authentication method. This + * policy is NOT RECOMMENDED unless it is unavoidable; see Section 7.5 + * of RFC 3711 (http://www.ietf.org/rfc/rfc3711.txt). + * + * This function is a convenience that helps to avoid dealing directly + * with the policy data structure. You are encouraged to initialize + * policy elements with this function call. Doing so may allow your + * code to be forward compatible with later versions of libSRTP that + * include more elements in the srtp_crypto_policy_t datatype. + * + * @warning This policy is NOT RECOMMENDED for SRTP unless it is + * unavoidable, and it is NOT RECOMMENDED at all for SRTCP; see + * Section 7.5 of RFC 3711 (http://www.ietf.org/rfc/rfc3711.txt). + * + * @return void. + * + */ +void srtp_crypto_policy_set_aes_cm_128_null_auth(srtp_crypto_policy_t *p); + +/** + * @brief srtp_crypto_policy_set_null_cipher_hmac_sha1_80() sets a crypto + * policy structure to an authentication-only policy + * + * @param p is a pointer to the policy structure to be set + * + * The function call srtp_crypto_policy_set_null_cipher_hmac_sha1_80(&p) + * sets the srtp_crypto_policy_t at location p to use HMAC-SHA1 with an 80 + * bit authentication tag to provide message authentication, but to + * use no encryption. This policy is NOT RECOMMENDED for SRTP unless + * there is a requirement to forgo encryption. + * + * This function is a convenience that helps to avoid dealing directly + * with the policy data structure. You are encouraged to initialize + * policy elements with this function call. Doing so may allow your + * code to be forward compatible with later versions of libSRTP that + * include more elements in the srtp_crypto_policy_t datatype. + * + * @warning This policy is NOT RECOMMENDED for SRTP unless there is a + * requirement to forgo encryption. + * + * @return void. + * + */ +void srtp_crypto_policy_set_null_cipher_hmac_sha1_80(srtp_crypto_policy_t *p); + +/** + * @brief srtp_crypto_policy_set_null_cipher_hmac_null() sets a crypto + * policy structure to use no encryption or authentication. + * + * @param p is a pointer to the policy structure to be set + * + * The function call srtp_crypto_policy_set_null_cipher_hmac_null(&p) + * sets the srtp_crypto_policy_t at location p to use no encryption and + * no authentication. This policy should only be used for testing and + * troubleshooting. + * + * This function is a convenience that helps to avoid dealing directly + * with the policy data structure. You are encouraged to initialize + * policy elements with this function call. Doing so may allow your + * code to be forward compatible with later versions of libSRTP that + * include more elements in the srtp_crypto_policy_t datatype. + * + * @warning This policy is NOT RECOMMENDED for SRTP unless there is a + * requirement to forgo encryption and authentication. + * + * @return void. + * + */ +void srtp_crypto_policy_set_null_cipher_hmac_null(srtp_crypto_policy_t *p); + +/** + * @brief srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80() sets a crypto + * policy structure to a encryption and authentication policy using AES-256 + * for RTP protection. + * + * @param p is a pointer to the policy structure to be set + * + * The function call srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&p) + * sets the srtp_crypto_policy_t at location p to use policy + * AES_CM_256_HMAC_SHA1_80 as defined in RFC 6188. This policy uses AES-256 + * Counter Mode encryption and HMAC-SHA1 authentication, with an 80 bit + * authentication tag. + * + * This function is a convenience that helps to avoid dealing directly + * with the policy data structure. You are encouraged to initialize + * policy elements with this function call. Doing so may allow your + * code to be forward compatible with later versions of libSRTP that + * include more elements in the srtp_crypto_policy_t datatype. + * + * @return void. + * + */ +void srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(srtp_crypto_policy_t *p); + +/** + * @brief srtp_crypto_policy_set_aes_cm_256_hmac_sha1_32() sets a crypto + * policy structure to a short-authentication tag policy using AES-256 + * encryption. + * + * @param p is a pointer to the policy structure to be set + * + * The function call srtp_crypto_policy_set_aes_cm_256_hmac_sha1_32(&p) + * sets the srtp_crypto_policy_t at location p to use policy + * AES_CM_256_HMAC_SHA1_32 as defined in RFC 6188. This policy uses AES-256 + * Counter Mode encryption and HMAC-SHA1 authentication, with an + * authentication tag that is only 32 bits long. This length is + * considered adequate only for protecting audio and video media that + * use a stateless playback function. See Section 7.5 of RFC 3711 + * (http://www.ietf.org/rfc/rfc3711.txt). + * + * This function is a convenience that helps to avoid dealing directly + * with the policy data structure. You are encouraged to initialize + * policy elements with this function call. Doing so may allow your + * code to be forward compatible with later versions of libSRTP that + * include more elements in the srtp_crypto_policy_t datatype. + * + * @warning This crypto policy is intended for use in SRTP, but not in + * SRTCP. It is recommended that a policy that uses longer + * authentication tags be used for SRTCP. See Section 7.5 of RFC 3711 + * (http://www.ietf.org/rfc/rfc3711.txt). + * + * @return void. + * + */ +void srtp_crypto_policy_set_aes_cm_256_hmac_sha1_32(srtp_crypto_policy_t *p); + +/** + * @brief srtp_crypto_policy_set_aes_cm_256_null_auth() sets a crypto + * policy structure to an encryption-only policy + * + * @param p is a pointer to the policy structure to be set + * + * The function call srtp_crypto_policy_set_aes_cm_256_null_auth(&p) sets + * the srtp_crypto_policy_t at location p to use the SRTP default cipher + * (AES-256 Counter Mode), but to use no authentication method. This + * policy is NOT RECOMMENDED unless it is unavoidable; see Section 7.5 + * of RFC 3711 (http://www.ietf.org/rfc/rfc3711.txt). + * + * This function is a convenience that helps to avoid dealing directly + * with the policy data structure. You are encouraged to initialize + * policy elements with this function call. Doing so may allow your + * code to be forward compatible with later versions of libSRTP that + * include more elements in the srtp_crypto_policy_t datatype. + * + * @warning This policy is NOT RECOMMENDED for SRTP unless it is + * unavoidable, and it is NOT RECOMMENDED at all for SRTCP; see + * Section 7.5 of RFC 3711 (http://www.ietf.org/rfc/rfc3711.txt). + * + * @return void. + * + */ +void srtp_crypto_policy_set_aes_cm_256_null_auth(srtp_crypto_policy_t *p); + +/** + * @brief srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80() sets a crypto + * policy structure to a encryption and authentication policy using AES-192 + * for RTP protection. + * + * @param p is a pointer to the policy structure to be set + * + * The function call srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(&p) + * sets the srtp_crypto_policy_t at location p to use policy + * AES_CM_192_HMAC_SHA1_80 as defined in RFC 6188. This policy uses AES-192 + * Counter Mode encryption and HMAC-SHA1 authentication, with an 80 bit + * authentication tag. + * + * This function is a convenience that helps to avoid dealing directly + * with the policy data structure. You are encouraged to initialize + * policy elements with this function call. Doing so may allow your + * code to be forward compatible with later versions of libSRTP that + * include more elements in the srtp_crypto_policy_t datatype. + * + * @return void. + * + */ +void srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(srtp_crypto_policy_t *p); + +/** + * @brief srtp_crypto_policy_set_aes_cm_192_hmac_sha1_32() sets a crypto + * policy structure to a short-authentication tag policy using AES-192 + * encryption. + * + * @param p is a pointer to the policy structure to be set + * + * The function call srtp_crypto_policy_set_aes_cm_192_hmac_sha1_32(&p) + * sets the srtp_crypto_policy_t at location p to use policy + * AES_CM_192_HMAC_SHA1_32 as defined in RFC 6188. This policy uses AES-192 + * Counter Mode encryption and HMAC-SHA1 authentication, with an + * authentication tag that is only 32 bits long. This length is + * considered adequate only for protecting audio and video media that + * use a stateless playback function. See Section 7.5 of RFC 3711 + * (http://www.ietf.org/rfc/rfc3711.txt). + * + * This function is a convenience that helps to avoid dealing directly + * with the policy data structure. You are encouraged to initialize + * policy elements with this function call. Doing so may allow your + * code to be forward compatible with later versions of libSRTP that + * include more elements in the srtp_crypto_policy_t datatype. + * + * @warning This crypto policy is intended for use in SRTP, but not in + * SRTCP. It is recommended that a policy that uses longer + * authentication tags be used for SRTCP. See Section 7.5 of RFC 3711 + * (http://www.ietf.org/rfc/rfc3711.txt). + * + * @return void. + * + */ +void srtp_crypto_policy_set_aes_cm_192_hmac_sha1_32(srtp_crypto_policy_t *p); + +/** + * @brief srtp_crypto_policy_set_aes_cm_192_null_auth() sets a crypto + * policy structure to an encryption-only policy + * + * @param p is a pointer to the policy structure to be set + * + * The function call srtp_crypto_policy_set_aes_cm_192_null_auth(&p) sets + * the srtp_crypto_policy_t at location p to use the SRTP default cipher + * (AES-192 Counter Mode), but to use no authentication method. This + * policy is NOT RECOMMENDED unless it is unavoidable; see Section 7.5 + * of RFC 3711 (http://www.ietf.org/rfc/rfc3711.txt). + * + * This function is a convenience that helps to avoid dealing directly + * with the policy data structure. You are encouraged to initialize + * policy elements with this function call. Doing so may allow your + * code to be forward compatible with later versions of libSRTP that + * include more elements in the srtp_crypto_policy_t datatype. + * + * @warning This policy is NOT RECOMMENDED for SRTP unless it is + * unavoidable, and it is NOT RECOMMENDED at all for SRTCP; see + * Section 7.5 of RFC 3711 (http://www.ietf.org/rfc/rfc3711.txt). + * + * @return void. + * + */ +void srtp_crypto_policy_set_aes_cm_192_null_auth(srtp_crypto_policy_t *p); + +/** + * @brief srtp_crypto_policy_set_aes_gcm_128_8_auth() sets a crypto + * policy structure to an AEAD encryption policy. + * + * @param p is a pointer to the policy structure to be set + * + * The function call srtp_crypto_policy_set_aes_gcm_128_8_auth(&p) sets + * the srtp_crypto_policy_t at location p to use the SRTP default cipher + * (AES-128 Galois Counter Mode) with 8 octet auth tag. This + * policy applies confidentiality and authentication to both the + * RTP and RTCP packets. + * + * This function is a convenience that helps to avoid dealing directly + * with the policy data structure. You are encouraged to initialize + * policy elements with this function call. Doing so may allow your + * code to be forward compatible with later versions of libSRTP that + * include more elements in the srtp_crypto_policy_t datatype. + * + * @return void. + * + */ +void srtp_crypto_policy_set_aes_gcm_128_8_auth(srtp_crypto_policy_t *p); + +/** + * @brief srtp_crypto_policy_set_aes_gcm_256_8_auth() sets a crypto + * policy structure to an AEAD encryption policy + * + * @param p is a pointer to the policy structure to be set + * + * The function call srtp_crypto_policy_set_aes_gcm_256_8_auth(&p) sets + * the srtp_crypto_policy_t at location p to use the SRTP default cipher + * (AES-256 Galois Counter Mode) with 8 octet auth tag. This + * policy applies confidentiality and authentication to both the + * RTP and RTCP packets. + * + * This function is a convenience that helps to avoid dealing directly + * with the policy data structure. You are encouraged to initialize + * policy elements with this function call. Doing so may allow your + * code to be forward compatible with later versions of libSRTP that + * include more elements in the srtp_crypto_policy_t datatype. + * + * @return void. + * + */ +void srtp_crypto_policy_set_aes_gcm_256_8_auth(srtp_crypto_policy_t *p); + +/** + * @brief srtp_crypto_policy_set_aes_gcm_128_8_only_auth() sets a crypto + * policy structure to an AEAD authentication-only policy + * + * @param p is a pointer to the policy structure to be set + * + * The function call srtp_crypto_policy_set_aes_gcm_128_8_only_auth(&p) sets + * the srtp_crypto_policy_t at location p to use the SRTP default cipher + * (AES-128 Galois Counter Mode) with 8 octet auth tag. This policy + * applies confidentiality and authentication to the RTP packets, + * but only authentication to the RTCP packets. + * + * This function is a convenience that helps to avoid dealing directly + * with the policy data structure. You are encouraged to initialize + * policy elements with this function call. Doing so may allow your + * code to be forward compatible with later versions of libSRTP that + * include more elements in the srtp_crypto_policy_t datatype. + * + * @return void. + * + */ +void srtp_crypto_policy_set_aes_gcm_128_8_only_auth(srtp_crypto_policy_t *p); + +/** + * @brief srtp_crypto_policy_set_aes_gcm_256_8_only_auth() sets a crypto + * policy structure to an AEAD authentication-only policy + * + * @param p is a pointer to the policy structure to be set + * + * The function call srtp_crypto_policy_set_aes_gcm_256_8_only_auth(&p) sets + * the srtp_crypto_policy_t at location p to use the SRTP default cipher + * (AES-256 Galois Counter Mode) with 8 octet auth tag. This policy + * applies confidentiality and authentication to the RTP packets, + * but only authentication to the RTCP packets. + * + * This function is a convenience that helps to avoid dealing directly + * with the policy data structure. You are encouraged to initialize + * policy elements with this function call. Doing so may allow your + * code to be forward compatible with later versions of libSRTP that + * include more elements in the srtp_crypto_policy_t datatype. + * + * @return void. + * + */ +void srtp_crypto_policy_set_aes_gcm_256_8_only_auth(srtp_crypto_policy_t *p); + +/** + * @brief srtp_crypto_policy_set_aes_gcm_128_16_auth() sets a crypto + * policy structure to an AEAD encryption policy. + * + * @param p is a pointer to the policy structure to be set + * + * The function call srtp_crypto_policy_set_aes_gcm_128_16_auth(&p) sets + * the srtp_crypto_policy_t at location p to use the SRTP default cipher + * (AES-128 Galois Counter Mode) with 16 octet auth tag. This + * policy applies confidentiality and authentication to both the + * RTP and RTCP packets. + * + * This function is a convenience that helps to avoid dealing directly + * with the policy data structure. You are encouraged to initialize + * policy elements with this function call. Doing so may allow your + * code to be forward compatible with later versions of libSRTP that + * include more elements in the srtp_crypto_policy_t datatype. + * + * @return void. + * + */ +void srtp_crypto_policy_set_aes_gcm_128_16_auth(srtp_crypto_policy_t *p); + +/** + * @brief srtp_crypto_policy_set_aes_gcm_256_16_auth() sets a crypto + * policy structure to an AEAD encryption policy + * + * @param p is a pointer to the policy structure to be set + * + * The function call srtp_crypto_policy_set_aes_gcm_256_16_auth(&p) sets + * the srtp_crypto_policy_t at location p to use the SRTP default cipher + * (AES-256 Galois Counter Mode) with 16 octet auth tag. This + * policy applies confidentiality and authentication to both the + * RTP and RTCP packets. + * + * This function is a convenience that helps to avoid dealing directly + * with the policy data structure. You are encouraged to initialize + * policy elements with this function call. Doing so may allow your + * code to be forward compatible with later versions of libSRTP that + * include more elements in the srtp_crypto_policy_t datatype. + * + * @return void. + * + */ +void srtp_crypto_policy_set_aes_gcm_256_16_auth(srtp_crypto_policy_t *p); + +/** + * @brief srtp_dealloc() deallocates storage for an SRTP session + * context. + * + * The function call srtp_dealloc(s) deallocates storage for the + * SRTP session context s. This function should be called no more + * than one time for each of the contexts allocated by the function + * srtp_create(). + * + * @param s is the srtp_t for the session to be deallocated. + * + * @return + * - srtp_err_status_ok if there no problems. + * - srtp_err_status_dealloc_fail a memory deallocation failure occurred. + */ +srtp_err_status_t srtp_dealloc(srtp_t s); + +/* + * @brief identifies a particular SRTP profile + * + * An srtp_profile_t enumeration is used to identify a particular SRTP + * profile (that is, a set of algorithms and parameters). + */ +typedef enum { + srtp_profile_reserved = 0, + srtp_profile_aes128_cm_sha1_80 = 1, + srtp_profile_aes128_cm_sha1_32 = 2, + srtp_profile_null_sha1_80 = 5, + srtp_profile_null_sha1_32 = 6, + srtp_profile_aead_aes_128_gcm = 7, + srtp_profile_aead_aes_256_gcm = 8, +} srtp_profile_t; + +/** + * @brief srtp_crypto_policy_set_from_profile_for_rtp() sets a crypto policy + * structure to the appropriate value for RTP based on an srtp_profile_t + * + * @param policy is a pointer to the policy structure to be set + * + * @param profile is an enumeration for the policy to be set + * + * The function call srtp_crypto_policy_set_rtp_default(&policy, profile) + * sets the srtp_crypto_policy_t at location policy to the policy for RTP + * protection, as defined by the srtp_profile_t profile. + * + * This function is a convenience that helps to avoid dealing directly + * with the policy data structure. You are encouraged to initialize + * policy elements with this function call. Doing so may allow your + * code to be forward compatible with later versions of libSRTP that + * include more elements in the srtp_crypto_policy_t datatype. + * + * @return values + * - srtp_err_status_ok no problems were encountered + * - srtp_err_status_bad_param the profile is not supported + * + */ +srtp_err_status_t srtp_crypto_policy_set_from_profile_for_rtp( + srtp_crypto_policy_t *policy, + srtp_profile_t profile); + +/** + * @brief srtp_crypto_policy_set_from_profile_for_rtcp() sets a crypto policy + * structure to the appropriate value for RTCP based on an srtp_profile_t + * + * @param policy is a pointer to the policy structure to be set + * + * @param profile is an enumeration for the policy to be set + * + * The function call srtp_crypto_policy_set_rtcp_default(&policy, profile) + * sets the srtp_crypto_policy_t at location policy to the policy for RTCP + * protection, as defined by the srtp_profile_t profile. + * + * This function is a convenience that helps to avoid dealing directly + * with the policy data structure. You are encouraged to initialize + * policy elements with this function call. Doing so may allow your + * code to be forward compatible with later versions of libSRTP that + * include more elements in the srtp_crypto_policy_t datatype. + * + * @return values + * - srtp_err_status_ok no problems were encountered + * - srtp_err_status_bad_param the profile is not supported + * + */ +srtp_err_status_t srtp_crypto_policy_set_from_profile_for_rtcp( + srtp_crypto_policy_t *policy, + srtp_profile_t profile); + +/** + * @brief returns the master key length for a given SRTP profile + */ +unsigned int srtp_profile_get_master_key_length(srtp_profile_t profile); + +/** + * @brief returns the master salt length for a given SRTP profile + */ +unsigned int srtp_profile_get_master_salt_length(srtp_profile_t profile); + +/** + * @brief appends the salt to the key + * + * The function call srtp_append_salt_to_key(k, klen, s, slen) + * copies the string s to the location at klen bytes following + * the location k. + * + * @warning There must be at least bytes_in_salt + bytes_in_key bytes + * available at the location pointed to by key. + * + */ +void srtp_append_salt_to_key(unsigned char *key, + unsigned int bytes_in_key, + unsigned char *salt, + unsigned int bytes_in_salt); + +/** + * @} + */ + +/** + * @defgroup SRTCP Secure RTCP + * @ingroup SRTP + * + * @brief Secure RTCP functions are used to protect RTCP traffic. + * + * RTCP is the control protocol for RTP. libSRTP protects RTCP + * traffic in much the same way as it does RTP traffic. The function + * srtp_protect_rtcp() applies cryptographic protections to outbound + * RTCP packets, and srtp_unprotect_rtcp() verifies the protections on + * inbound RTCP packets. + * + * A note on the naming convention: srtp_protect_rtcp() has an srtp_t + * as its first argument, and thus has `srtp_' as its prefix. The + * trailing `_rtcp' indicates the protocol on which it acts. + * + * @{ + */ + +/** + * @brief srtp_protect_rtcp() is the Secure RTCP sender-side packet + * processing function. + * + * The function call srtp_protect_rtcp(ctx, rtp_hdr, len_ptr) applies + * SRTCP protection to the RTCP packet rtcp_hdr (which has length + * *len_ptr) using the SRTP session context ctx. If srtp_err_status_ok is + * returned, then rtp_hdr points to the resulting SRTCP packet and + * *len_ptr is the number of octets in that packet; otherwise, no + * assumptions should be made about the value of either data elements. + * + * @warning This function assumes that it can write the authentication + * tag into the location in memory immediately following the RTCP + * packet, and assumes that the RTCP packet is aligned on a 32-bit + * boundary. + * + * @warning This function assumes that it can write SRTP_MAX_TRAILER_LEN+4 + * into the location in memory immediately following the RTCP packet. + * Callers MUST ensure that this much writable memory is available in + * the buffer that holds the RTCP packet. + * + * @param ctx is the SRTP context to use in processing the packet. + * + * @param rtcp_hdr is a pointer to the RTCP packet (before the call); after + * the function returns, it points to the srtp packet. + * + * @param pkt_octet_len is a pointer to the length in octets of the + * complete RTCP packet (header and body) before the function call, + * and of the complete SRTCP packet after the call, if srtp_err_status_ok + * was returned. Otherwise, the value of the data to which it points + * is undefined. + * + * @return + * - srtp_err_status_ok if there were no problems. + * - [other] if there was a failure in + * the cryptographic mechanisms. + */ +srtp_err_status_t srtp_protect_rtcp(srtp_t ctx, + void *rtcp_hdr, + int *pkt_octet_len); + +/** + * @brief srtp_protect_rtcp_mki() is the Secure RTCP sender-side packet + * processing function that can utilize mki. + * + * The function call srtp_protect_rtcp(ctx, rtp_hdr, len_ptr) applies + * SRTCP protection to the RTCP packet rtcp_hdr (which has length + * *len_ptr) using the SRTP session context ctx. If srtp_err_status_ok is + * returned, then rtp_hdr points to the resulting SRTCP packet and + * *len_ptr is the number of octets in that packet; otherwise, no + * assumptions should be made about the value of either data elements. + * + * @warning This function assumes that it can write the authentication + * tag into the location in memory immediately following the RTCP + * packet, and assumes that the RTCP packet is aligned on a 32-bit + * boundary. + * + * @warning This function assumes that it can write SRTP_MAX_TRAILER_LEN+4 + * into the location in memory immediately following the RTCP packet. + * Callers MUST ensure that this much writable memory is available in + * the buffer that holds the RTCP packet. + * + * @param ctx is the SRTP context to use in processing the packet. + * + * @param rtcp_hdr is a pointer to the RTCP packet (before the call); after + * the function returns, it points to the srtp packet. + * + * @param pkt_octet_len is a pointer to the length in octets of the + * complete RTCP packet (header and body) before the function call, + * and of the complete SRTCP packet after the call, if srtp_err_status_ok + * was returned. Otherwise, the value of the data to which it points + * is undefined. + * + * @param use_mki is a boolean to tell the system if mki is being used. If + * set to false then will use the first set of session keys. If set to true + * will + * use the session keys identified by the mki_index + * + * @param mki_index integer value specifying which set of session keys should be + * used if use_mki is set to true. + * + * @return + * - srtp_err_status_ok if there were no problems. + * - [other] if there was a failure in + * the cryptographic mechanisms. + */ +srtp_err_status_t srtp_protect_rtcp_mki(srtp_t ctx, + void *rtcp_hdr, + int *pkt_octet_len, + unsigned int use_mki, + unsigned int mki_index); + +/** + * @brief srtp_unprotect_rtcp() is the Secure RTCP receiver-side packet + * processing function. + * + * The function call srtp_unprotect_rtcp(ctx, srtp_hdr, len_ptr) + * verifies the Secure RTCP protection of the SRTCP packet pointed to + * by srtcp_hdr (which has length *len_ptr), using the SRTP session + * context ctx. If srtp_err_status_ok is returned, then srtcp_hdr points + * to the resulting RTCP packet and *len_ptr is the number of octets + * in that packet; otherwise, no assumptions should be made about the + * value of either data elements. + * + * @warning This function assumes that the SRTCP packet is aligned on a + * 32-bit boundary. + * + * @param ctx is a pointer to the srtp_t which applies to the + * particular packet. + * + * @param srtcp_hdr is a pointer to the header of the SRTCP packet + * (before the call). After the function returns, it points to the + * rtp packet if srtp_err_status_ok was returned; otherwise, the value of + * the data to which it points is undefined. + * + * @param pkt_octet_len is a pointer to the length in octets of the + * complete SRTCP packet (header and body) before the function call, + * and of the complete rtp packet after the call, if srtp_err_status_ok was + * returned. Otherwise, the value of the data to which it points is + * undefined. + * + * @return + * - srtp_err_status_ok if the RTCP packet is valid. + * - srtp_err_status_auth_fail if the SRTCP packet failed the message + * authentication check. + * - srtp_err_status_replay_fail if the SRTCP packet is a replay (e.g. has + * already been processed and accepted). + * - [other] if there has been an error in the cryptographic mechanisms. + * + */ +srtp_err_status_t srtp_unprotect_rtcp(srtp_t ctx, + void *srtcp_hdr, + int *pkt_octet_len); + +/** + * @brief srtp_unprotect_rtcp() is the Secure RTCP receiver-side packet + * processing function. + * + * The function call srtp_unprotect_rtcp(ctx, srtp_hdr, len_ptr) + * verifies the Secure RTCP protection of the SRTCP packet pointed to + * by srtcp_hdr (which has length *len_ptr), using the SRTP session + * context ctx. If srtp_err_status_ok is returned, then srtcp_hdr points + * to the resulting RTCP packet and *len_ptr is the number of octets + * in that packet; otherwise, no assumptions should be made about the + * value of either data elements. + * + * @warning This function assumes that the SRTCP packet is aligned on a + * 32-bit boundary. + * + * @param ctx is a pointer to the srtp_t which applies to the + * particular packet. + * + * @param srtcp_hdr is a pointer to the header of the SRTCP packet + * (before the call). After the function returns, it points to the + * rtp packet if srtp_err_status_ok was returned; otherwise, the value of + * the data to which it points is undefined. + * + * @param pkt_octet_len is a pointer to the length in octets of the + * complete SRTCP packet (header and body) before the function call, + * and of the complete rtp packet after the call, if srtp_err_status_ok was + * returned. Otherwise, the value of the data to which it points is + * undefined. + * + * @param use_mki is a boolean to tell the system if mki is being used. If + * set to false then will use the first set of session keys. If set to true + * will use the session keys identified by the mki_index + * + * @return + * - srtp_err_status_ok if the RTCP packet is valid. + * - srtp_err_status_auth_fail if the SRTCP packet failed the message + * authentication check. + * - srtp_err_status_replay_fail if the SRTCP packet is a replay (e.g. has + * already been processed and accepted). + * - srtp_err_status_bad_mki if the MKI in the packet is not a known MKI + * id + * - [other] if there has been an error in the + * cryptographic mechanisms. + * + */ +srtp_err_status_t srtp_unprotect_rtcp_mki(srtp_t ctx, + void *srtcp_hdr, + int *pkt_octet_len, + unsigned int use_mki); + +/** + * @} + */ + +/** + * @defgroup User data associated to a SRTP session. + * @ingroup SRTP + * + * @brief Store custom user data within a SRTP session. + * + * @{ + */ + +/** + * @brief srtp_set_user_data() stores the given pointer into the SRTP + * session for later retrieval. + * + * @param ctx is the srtp_t context in which the given data pointer is + * stored. + * + * @param data is a pointer to the custom information (struct, function, + * etc) associated with the SRTP session. + * + * @return void. + * + */ +void srtp_set_user_data(srtp_t ctx, void *data); + +/** + * @brief srtp_get_user_data() retrieves the pointer to the custom data + * previously stored with srtp_set_user_data(). + * + * This function is mostly useful for retrieving data associated to a + * SRTP session when an event fires. The user can then get such a custom + * data by calling this function with the session field of the + * srtp_event_data_t struct as argument. + * + * @param ctx is the srtp_t context in which the given data pointer was + * stored. + * + * @return void* pointer to the user data. + * + */ +void *srtp_get_user_data(srtp_t ctx); + +/** + * @} + */ + +/** + * @defgroup SRTPevents SRTP events and callbacks + * @ingroup SRTP + * + * @brief libSRTP can use a user-provided callback function to + * handle events. + * + * + * libSRTP allows a user to provide a callback function to handle + * events that need to be dealt with outside of the data plane (see + * the enum srtp_event_t for a description of these events). Dealing + * with these events is not a strict necessity; they are not + * security-critical, but the application may suffer if they are not + * handled. The function srtp_set_event_handler() is used to provide + * the callback function. + * + * A default event handler that merely reports on the events as they + * happen is included. It is also possible to set the event handler + * function to NULL, in which case all events will just be silently + * ignored. + * + * @{ + */ + +/** + * @brief srtp_event_t defines events that need to be handled + * + * The enum srtp_event_t defines events that need to be handled + * outside the `data plane', such as SSRC collisions and + * key expirations. + * + * When a key expires or the maximum number of packets has been + * reached, an SRTP stream will enter an `expired' state in which no + * more packets can be protected or unprotected. When this happens, + * it is likely that you will want to either deallocate the stream + * (using srtp_remove_stream()), and possibly allocate a new one. + * + * When an SRTP stream expires, the other streams in the same session + * are unaffected, unless key sharing is used by that stream. In the + * latter case, all of the streams in the session will expire. + */ +typedef enum { + event_ssrc_collision, /**< An SSRC collision occurred. */ + event_key_soft_limit, /**< An SRTP stream reached the soft key */ + /**< usage limit and will expire soon. */ + event_key_hard_limit, /**< An SRTP stream reached the hard */ + /**< key usage limit and has expired. */ + event_packet_index_limit /**< An SRTP stream reached the hard */ + /**< packet limit (2^48 packets). */ +} srtp_event_t; + +/** + * @brief srtp_event_data_t is the structure passed as a callback to + * the event handler function + * + * The struct srtp_event_data_t holds the data passed to the event + * handler function. + */ +typedef struct srtp_event_data_t { + srtp_t session; /**< The session in which the event happened. */ + uint32_t ssrc; /**< The ssrc in host order of the stream in which */ + /**< the event happened */ + srtp_event_t event; /**< An enum indicating the type of event. */ +} srtp_event_data_t; + +/** + * @brief srtp_event_handler_func_t is the function prototype for + * the event handler. + * + * The typedef srtp_event_handler_func_t is the prototype for the + * event handler function. It has as its only argument an + * srtp_event_data_t which describes the event that needs to be handled. + * There can only be a single, global handler for all events in + * libSRTP. + */ +typedef void(srtp_event_handler_func_t)(srtp_event_data_t *data); + +/** + * @brief sets the event handler to the function supplied by the caller. + * + * The function call srtp_install_event_handler(func) sets the event + * handler function to the value func. The value NULL is acceptable + * as an argument; in this case, events will be ignored rather than + * handled. + * + * @param func is a pointer to a function that takes an srtp_event_data_t + * pointer as an argument and returns void. This function + * will be used by libSRTP to handle events. + */ +srtp_err_status_t srtp_install_event_handler(srtp_event_handler_func_t func); + +/** + * @brief Returns the version string of the library. + * + */ +const char *srtp_get_version_string(void); + +/** + * @brief Returns the numeric representation of the library version. + * + */ +unsigned int srtp_get_version(void); + +/** + * @brief srtp_set_debug_module(mod_name, v) + * + * sets dynamic debugging to the value v (0 for off, 1 for on) for the + * debug module with the name mod_name + * + * returns err_status_ok on success, err_status_fail otherwise + */ +srtp_err_status_t srtp_set_debug_module(const char *mod_name, int v); + +/** + * @brief srtp_list_debug_modules() outputs a list of debugging modules + * + */ +srtp_err_status_t srtp_list_debug_modules(void); + +/** + * @brief srtp_log_level_t defines log levels. + * + * The enumeration srtp_log_level_t defines log levels reported + * in the srtp_log_handler_func_t. + * + */ +typedef enum { + srtp_log_level_error, /**< log level is reporting an error message */ + srtp_log_level_warning, /**< log level is reporting a warning message */ + srtp_log_level_info, /**< log level is reporting an info message */ + srtp_log_level_debug /**< log level is reporting a debug message */ +} srtp_log_level_t; + +/** + * @brief srtp_log_handler_func_t is the function prototype for + * the log handler. + * + * The typedef srtp_event_handler_func_t is the prototype for the + * event handler function. It has as srtp_log_level_t, log + * message and data as arguments. + * There can only be a single, global handler for all log messages in + * libSRTP. + */ +typedef void(srtp_log_handler_func_t)(srtp_log_level_t level, + const char *msg, + void *data); + +/** + * @brief sets the log handler to the function supplied by the caller. + * + * The function call srtp_install_log_handler(func) sets the log + * handler function to the value func. The value NULL is acceptable + * as an argument; in this case, log messages will be ignored. + * This function can be called before srtp_init() in order to capture + * any logging during start up. + * + * @param func is a pointer to a function of type srtp_log_handler_func_t. + * This function will be used by libSRTP to output log messages. + * @param data is a user pointer that will be returned as the data argument in + * func. + */ +srtp_err_status_t srtp_install_log_handler(srtp_log_handler_func_t func, + void *data); + +/** + * @brief srtp_get_protect_trailer_length(session, use_mki, mki_index, length) + * + * Determines the length of the amount of data Lib SRTP will add to the + * packet during the protect process. The length is returned in the length + * parameter + * + * returns err_status_ok on success, err_status_bad_mki if the MKI index is + * invalid + * + */ +srtp_err_status_t srtp_get_protect_trailer_length(srtp_t session, + uint32_t use_mki, + uint32_t mki_index, + uint32_t *length); + +/** + * @brief srtp_get_protect_rtcp_trailer_length(session, use_mki, mki_index, + * length) + * + * Determines the length of the amount of data Lib SRTP will add to the + * packet during the protect process. The length is returned in the length + * parameter + * + * returns err_status_ok on success, err_status_bad_mki if the MKI index is + * invalid + * + */ +srtp_err_status_t srtp_get_protect_rtcp_trailer_length(srtp_t session, + uint32_t use_mki, + uint32_t mki_index, + uint32_t *length); + +/** + * @brief srtp_set_stream_roc(session, ssrc, roc) + * + * Set the roll-over-counter on a session for a given SSRC + * + * returns err_status_ok on success, srtp_err_status_bad_param if there is no + * stream found + * + */ +srtp_err_status_t srtp_set_stream_roc(srtp_t session, + uint32_t ssrc, + uint32_t roc); + +/** + * @brief srtp_get_stream_roc(session, ssrc, roc) + * + * Get the roll-over-counter on a session for a given SSRC + * + * returns err_status_ok on success, srtp_err_status_bad_param if there is no + * stream found + * + */ +srtp_err_status_t srtp_get_stream_roc(srtp_t session, + uint32_t ssrc, + uint32_t *roc); + +/** + * @} + */ + +/* in host order, so outside the #if */ +#define SRTCP_E_BIT 0x80000000 + +/* for byte-access */ +#define SRTCP_E_BYTE_BIT 0x80 +#define SRTCP_INDEX_MASK 0x7fffffff + +#ifdef __cplusplus +} +#endif + +#endif /* SRTP_SRTP_H */ diff --git a/Android/app/src/main/java/com/zlmediakit/demo/MainActivity.java b/Android/app/src/main/java/com/zlmediakit/demo/MainActivity.java index 05eba135..e253d3c0 100644 --- a/Android/app/src/main/java/com/zlmediakit/demo/MainActivity.java +++ b/Android/app/src/main/java/com/zlmediakit/demo/MainActivity.java @@ -34,7 +34,7 @@ public class MainActivity extends AppCompatActivity { } } - String sd_dir = Environment.getExternalStoragePublicDirectory("").toString(); + String sd_dir = Environment.getExternalStoragePublicDirectory("zlmediakit").toString(); if(permissionSuccess){ Toast.makeText(this,"你可以修改配置文件再启动:" + sd_dir + "/zlmediakit.ini" ,Toast.LENGTH_LONG).show(); Toast.makeText(this,"SSL证书请放置在:" + sd_dir + "/zlmediakit.pem" ,Toast.LENGTH_LONG).show(); diff --git a/Android/build.gradle b/Android/build.gradle index 95a39961..f817a65f 100644 --- a/Android/build.gradle +++ b/Android/build.gradle @@ -7,7 +7,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:4.0.1' + classpath 'com.android.tools.build:gradle:7.2.2' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/Android/gradle/wrapper/gradle-wrapper.jar b/Android/gradle/wrapper/gradle-wrapper.jar index f6b961fd..7454180f 100644 Binary files a/Android/gradle/wrapper/gradle-wrapper.jar and b/Android/gradle/wrapper/gradle-wrapper.jar differ diff --git a/Android/gradle/wrapper/gradle-wrapper.properties b/Android/gradle/wrapper/gradle-wrapper.properties index 0a81a846..d582a97e 100644 --- a/Android/gradle/wrapper/gradle-wrapper.properties +++ b/Android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Sun Jun 19 15:19:24 CST 2022 +#Fri Dec 22 09:27:45 CST 2023 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip diff --git a/Android/gradlew b/Android/gradlew index cccdd3d5..3da45c16 100755 --- a/Android/gradlew +++ b/Android/gradlew @@ -1,78 +1,129 @@ -#!/usr/bin/env sh +#!/bin/sh + +# +# Copyright ? 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions ?$var?, ?${var}?, ?${var:-default}?, ?${var+SET}?, +# ?${var#prefix}?, ?${var%suffix}?, and ?$( cmd )?; +# * compound commands having a testable exit status, especially ?case?; +# * various built-in commands including ?command?, ?set?, and ?ulimit?. +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` +APP_BASE_NAME=${0##*/} # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -81,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" + JAVACMD=java which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the @@ -89,84 +140,95 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=$(save "$@") +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done fi +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + exec "$JAVACMD" "$@" diff --git a/Android/gradlew.bat b/Android/gradlew.bat index f9553162..107acd32 100644 --- a/Android/gradlew.bat +++ b/Android/gradlew.bat @@ -1,3 +1,19 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @@ -13,15 +29,18 @@ if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if "%ERRORLEVEL%" == "0" goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -35,7 +54,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -45,28 +64,14 @@ echo location of your Java installation. goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell diff --git a/README.md b/README.md index 60e8078b..f4b65c3e 100644 --- a/README.md +++ b/README.md @@ -191,6 +191,7 @@ bash build_docker_images.sh - [jessibuca](https://github.com/langhuihui/jessibuca) 基于wasm支持H265的播放器 - [wsPlayer](https://github.com/v354412101/wsPlayer) 基于MSE的websocket-fmp4播放器 - [BXC_gb28181Player](https://github.com/any12345com/BXC_gb28181Player) C++开发的支持国标GB28181协议的视频流播放器 + - [RTCPlayer](https://github.com/leo94666/RTCPlayer) 一个基于Android客户端的的RTC播放器 - WEB管理网站 - [zlm_webassist](https://github.com/1002victor/zlm_webassist) 本项目配套的前后端分离web管理项目 @@ -366,6 +367,7 @@ bash build_docker_images.sh [jamesZHANG500](https://github.com/jamesZHANG500) [weidelong](https://github.com/wdl1697454803) [小强先生](https://github.com/linshangqiang) +[李之阳](https://github.com/leo94666) 同时感谢JetBrains对开源项目的支持,本项目使用CLion开发与调试: diff --git a/server/main.cpp b/server/main.cpp index f418f2f8..8071ffef 100644 --- a/server/main.cpp +++ b/server/main.cpp @@ -319,6 +319,7 @@ int start_main(int argc,char *argv[]) { #endif//defined(ENABLE_RTPPROXY) #if defined(ENABLE_WEBRTC) + InfoL << "已启动webrtc"; auto rtcSrv_tcp = std::make_shared(); //webrtc udp服务器 auto rtcSrv_udp = std::make_shared(); diff --git a/webrtc_player/android/.gitignore b/webrtc_player/android/.gitignore index d4c3a57e..aa724b77 100644 --- a/webrtc_player/android/.gitignore +++ b/webrtc_player/android/.gitignore @@ -13,4 +13,3 @@ .externalNativeBuild .cxx local.properties -/.idea/ diff --git a/webrtc_player/android/.idea/.gitignore b/webrtc_player/android/.idea/.gitignore new file mode 100644 index 00000000..26d33521 --- /dev/null +++ b/webrtc_player/android/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/webrtc_player/android/.idea/.name b/webrtc_player/android/.idea/.name new file mode 100644 index 00000000..377c1793 --- /dev/null +++ b/webrtc_player/android/.idea/.name @@ -0,0 +1 @@ +RTCPlayer \ No newline at end of file diff --git a/webrtc_player/android/.idea/compiler.xml b/webrtc_player/android/.idea/compiler.xml new file mode 100644 index 00000000..b589d56e --- /dev/null +++ b/webrtc_player/android/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/webrtc_player/android/.idea/deploymentTargetDropDown.xml b/webrtc_player/android/.idea/deploymentTargetDropDown.xml new file mode 100644 index 00000000..0c0c3383 --- /dev/null +++ b/webrtc_player/android/.idea/deploymentTargetDropDown.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/webrtc_player/android/.idea/gradle.xml b/webrtc_player/android/.idea/gradle.xml new file mode 100644 index 00000000..0897082f --- /dev/null +++ b/webrtc_player/android/.idea/gradle.xml @@ -0,0 +1,19 @@ + + + + + + + \ No newline at end of file diff --git a/webrtc_player/android/.idea/kotlinc.xml b/webrtc_player/android/.idea/kotlinc.xml new file mode 100644 index 00000000..8d81632f --- /dev/null +++ b/webrtc_player/android/.idea/kotlinc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/webrtc_player/android/.idea/migrations.xml b/webrtc_player/android/.idea/migrations.xml new file mode 100644 index 00000000..f8051a6f --- /dev/null +++ b/webrtc_player/android/.idea/migrations.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/webrtc_player/android/.idea/misc.xml b/webrtc_player/android/.idea/misc.xml new file mode 100644 index 00000000..8978d23d --- /dev/null +++ b/webrtc_player/android/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/webrtc_player/android/.idea/vcs.xml b/webrtc_player/android/.idea/vcs.xml new file mode 100644 index 00000000..b2bdec2d --- /dev/null +++ b/webrtc_player/android/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/webrtc_player/android/README.md b/webrtc_player/android/README.md new file mode 100644 index 00000000..8889ccee --- /dev/null +++ b/webrtc_player/android/README.md @@ -0,0 +1,106 @@ +# RTCPlayer 播放器 + +一个基于Android客户端的的RTC播放器 + +## 项目特点 + +- :white_check_mark:低延迟(200~500ms) +- :white_check_mark:支持[ZLMediakit](https://github.com/ZLMediaKit/ZLMediaKit)流媒体 +- :black_square_button:支持[SRS](https://github.com/ossrs/srs) +- :black_square_button:支持[Janus](https://github.com/meetecho/janus-gateway) + +如果您需要支持SRS或者Janus,请寻找下方联系我! + +

+     +     + +

+ +## 延迟情况 + +- **网页端推流,Android端播放** + +

+     +     + +

+ +三次延迟分别为:490ms、526ms、560ms + +- **Android端推屏幕流,网页端播放** + +

+     +     + +

+ +三次延迟分别为:440ms、430ms、387ms + +## 接口说明 + +### Player + +- bind(surface: RTCSurfaceView) + + 绑定视图 + +- play(app: String, streamId: String) + + 播放 +- setVolume(volume:Float) + + 设置音量,范围: 0.0~1.0f +- stop() + + 停止播放 +- pause() + + 暂停播放 +- resume() + + 恢复播放 +- capture(listener: (bitmap: Bitmap) -> Unit) + + 截图 +- record(duration: Long, result: (path: String) -> Unit) + + 录制 +- setOnErrorListener(listener: (code: Int, msg: String) -> Unit) + + 设置播放器错误监听回调 +- setOnStatusListener(listener: (status: Status) -> Unit) + + 设置播放器状态回调 + +### Pusher + +- bind(surface: RTCSurfaceView, localPreview: Boolean) + + 绑定视图 + +- push(app: String, streamId: String, mode: PushMode = PushMode.CAMERA, inputFile: String = "") + + 推流,支持Camera、Screen、File + +- stop() + + 停止推流 + +- setOnErrorListener(listener: (code: Int, msg: String) -> Unit) + + 设置播放器错误监听回调 + +## 联系作者 +如果您需要深度二次开发,深度优化延迟,并支持其他流媒体服务,可以找我哦! +[李之阳](https://github.com/leo94666) + +## 特别感谢 + +感谢[ZLMediakit](https://github.com/ZLMediaKit/ZLMediaKit)开源项目 + +同时感谢JetBrains对开源项目的支持,本项目使用Android Studio开发与调试: + +[![Android Studio](https://th.bing.com/th?id=ODLS.d2ea10a5-5792-4f82-bd13-1595fd9d969c&w=32&h=32&qlt=90&pcl=fffffa&o=6&pid=1.2)](https://developer.android.com/studio?hl=zh-cn) \ No newline at end of file diff --git a/webrtc_player/android/app-debug.apk b/webrtc_player/android/app-debug.apk deleted file mode 100644 index 969d48b7..00000000 Binary files a/webrtc_player/android/app-debug.apk and /dev/null differ diff --git a/webrtc_player/android/app/.gitignore b/webrtc_player/android/app/.gitignore index c591fdeb..42afabfd 100644 --- a/webrtc_player/android/app/.gitignore +++ b/webrtc_player/android/app/.gitignore @@ -1,2 +1 @@ -/build -.cxx \ No newline at end of file +/build \ No newline at end of file diff --git a/webrtc_player/android/app/build.gradle b/webrtc_player/android/app/build.gradle deleted file mode 100644 index cfd25638..00000000 --- a/webrtc_player/android/app/build.gradle +++ /dev/null @@ -1,54 +0,0 @@ -plugins { - id 'com.android.application' - id 'org.jetbrains.kotlin.android' - id 'kotlin-android-extensions' - id 'kotlin-kapt' - -} -apply plugin: 'kotlin-android' - -android { - compileSdk 32 - - defaultConfig { - applicationId "com.zlmediakit.webrtc" - minSdk 21 - targetSdk 32 - versionCode 1 - versionName "1.0" - - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - } - - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' - } - } - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - kotlinOptions { - jvmTarget = '1.8' - } -} - -dependencies { - - implementation 'androidx.core:core-ktx:1.7.0' - implementation 'androidx.appcompat:appcompat:1.5.1' - implementation 'com.google.android.material:material:1.6.1' - implementation 'androidx.constraintlayout:constraintlayout:2.1.4' - testImplementation 'junit:junit:4.13.2' - androidTestImplementation 'androidx.test.ext:junit:1.1.3' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' - implementation 'com.google.code.gson:gson:2.8.9' - - implementation("com.squareup.okhttp3:okhttp:4.10.0") - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - - implementation 'org.webrtc:google-webrtc:1.0.32006' - -} \ No newline at end of file diff --git a/webrtc_player/android/app/build.gradle.kts b/webrtc_player/android/app/build.gradle.kts new file mode 100644 index 00000000..9ca6cebf --- /dev/null +++ b/webrtc_player/android/app/build.gradle.kts @@ -0,0 +1,58 @@ +plugins { + id("com.android.application") + id("org.jetbrains.kotlin.android") + +} + +android { + namespace = "com.top.player" + compileSdk = 34 + + defaultConfig { + applicationId = "com.top.player" + minSdk = 24 + targetSdk = 34 + versionCode = 1 + versionName = "1.0" + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = "1.8" + } + viewBinding { + enable = true + } +} + +dependencies { + + implementation("androidx.appcompat:appcompat:1.5.1") + implementation("com.google.android.material:material:1.6.1") + implementation("androidx.constraintlayout:constraintlayout:2.1.4") + testImplementation("junit:junit:4.13.2") + androidTestImplementation("androidx.test.ext:junit:1.1.3") + androidTestImplementation("androidx.test.espresso:espresso-core:3.4.0") + + implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.22") + implementation("com.guolindev.permissionx:permissionx:1.7.1") + + //implementation(project(":RTCPlayer")) + implementation("com.rtc.core:RTCPlayer:1.0.0.beta") + +} \ No newline at end of file diff --git a/webrtc_player/android/app/src/androidTest/java/com/top/player/ExampleInstrumentedTest.java b/webrtc_player/android/app/src/androidTest/java/com/top/player/ExampleInstrumentedTest.java new file mode 100644 index 00000000..2c5af40e --- /dev/null +++ b/webrtc_player/android/app/src/androidTest/java/com/top/player/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.top.player; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + assertEquals("com.top.player", appContext.getPackageName()); + } +} \ No newline at end of file diff --git a/webrtc_player/android/app/src/androidTest/java/com/zlmediakit/webrtc/ExampleInstrumentedTest.kt b/webrtc_player/android/app/src/androidTest/java/com/zlmediakit/webrtc/ExampleInstrumentedTest.kt deleted file mode 100644 index 645a1102..00000000 --- a/webrtc_player/android/app/src/androidTest/java/com/zlmediakit/webrtc/ExampleInstrumentedTest.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.zlmediakit.webrtc - -import androidx.test.platform.app.InstrumentationRegistry -import androidx.test.ext.junit.runners.AndroidJUnit4 - -import org.junit.Test -import org.junit.runner.RunWith - -import org.junit.Assert.* - -/** - * Instrumented test, which will execute on an Android device. - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -@RunWith(AndroidJUnit4::class) -class ExampleInstrumentedTest { - @Test - fun useAppContext() { - // Context of the app under test. - val appContext = InstrumentationRegistry.getInstrumentation().targetContext - assertEquals("com.zlmediakit.webrtc", appContext.packageName) - } -} \ No newline at end of file diff --git a/webrtc_player/android/app/src/main/AndroidManifest.xml b/webrtc_player/android/app/src/main/AndroidManifest.xml index 81281350..1e944e3c 100644 --- a/webrtc_player/android/app/src/main/AndroidManifest.xml +++ b/webrtc_player/android/app/src/main/AndroidManifest.xml @@ -1,24 +1,27 @@ + xmlns:tools="http://schemas.android.com/tools"> - - + + + android:required="true" /> + + + + + + + + + + + + + + - - - - - - - - - - + android:hardwareAccelerated="true" + tools:overrideLibrary="com.rtc.core" + android:name=".App"> @@ -41,6 +45,13 @@ + + + \ No newline at end of file diff --git a/webrtc_player/android/app/src/main/java/com/top/player/App.kt b/webrtc_player/android/app/src/main/java/com/top/player/App.kt new file mode 100644 index 00000000..1c457ffd --- /dev/null +++ b/webrtc_player/android/app/src/main/java/com/top/player/App.kt @@ -0,0 +1,11 @@ +package com.top.player + +import android.app.Application + +class App: Application() { + + override fun onCreate() { + super.onCreate() + + } +} \ No newline at end of file diff --git a/webrtc_player/android/app/src/main/java/com/top/player/MainActivity.kt b/webrtc_player/android/app/src/main/java/com/top/player/MainActivity.kt new file mode 100644 index 00000000..8cb2a7e5 --- /dev/null +++ b/webrtc_player/android/app/src/main/java/com/top/player/MainActivity.kt @@ -0,0 +1,25 @@ +package com.top.player + +import android.content.Intent +import android.os.Bundle +import android.view.View +import androidx.appcompat.app.AppCompatActivity + +class MainActivity : AppCompatActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_main) + + } + + fun toPlayActivity(view: View) { + startActivity(Intent(this, PlayerDemoActivity::class.java)) + } + + fun toPushActivity(view: View) { + startActivity(Intent(this, PusherDemoActivity::class.java)) + + } + +} \ No newline at end of file diff --git a/webrtc_player/android/app/src/main/java/com/top/player/PlayerDemoActivity.kt b/webrtc_player/android/app/src/main/java/com/top/player/PlayerDemoActivity.kt new file mode 100644 index 00000000..50f810cb --- /dev/null +++ b/webrtc_player/android/app/src/main/java/com/top/player/PlayerDemoActivity.kt @@ -0,0 +1,112 @@ +package com.top.player + +import android.os.Bundle +import android.view.View +import android.widget.Toast +import androidx.appcompat.app.AppCompatActivity +import com.rtc.core.ZLMRTCPlayer +import com.rtc.core.play.Status +import com.rtc.core.play.ZLMRTCPlayerImpl +import com.top.player.databinding.ActivityPlayerBinding + + +class PlayerDemoActivity : AppCompatActivity() { + + + private val player: ZLMRTCPlayer by lazy { + ZLMRTCPlayerImpl(this) + } + + + private val binding by lazy { + ActivityPlayerBinding.inflate(layoutInflater) + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + setContentView(binding.root) + + //ffmpeg -re -stream_loop -1 -i "D:\li\hot\data\data\baseline.mp4" -vcodec h264 -acodec aac -f rtsp -rtsp_transport tcp -bf 0 rtsp://zlmediakit.com/live/li + //ffmpeg -re -stream_loop -1 -i "D:\li\hot\data\data\test.mp4" -vcodec h264 -acodec aac -f flv -bf 0 rtmp://zlmediakit.com/live/li + + setTitle("Player Demo") + player.bind(binding.surfaceViewRender) + + player.setOnErrorListener { code, msg -> + Toast.makeText(this, "code:$code,msg:${msg}", Toast.LENGTH_SHORT).show() + + } + + player.setOnStatusListener { + when (it) { + Status.PREPARING -> { + binding.tvStatus.text = "准备播放" + } + + Status.PLAYING -> { + binding.tvStatus.text = "播放中.." + } + + Status.PAUSE -> { + binding.tvStatus.text = "暂停中.." + } + + Status.RESUME -> { + binding.tvStatus.text = "播放中.." + } + + Status.STOP -> { + binding.tvStatus.text = "" + } + + Status.ERROR -> { + binding.tvStatus.text = "播放异常" + } + + else -> {} + } + } + + } + + + override fun onDestroy() { + super.onDestroy() + player.stop() + } + + fun onPlayClick(view: View) { + + player.play(binding.tvApp.text.toString(), binding.tvStreamId.text.toString()) + } + + fun onPauseClick(view: View) { + player.pause() + //Toast.makeText(this, "ok", Toast.LENGTH_SHORT).show() + } + + fun onStopClick(view: View) { + player.stop() + } + + fun onResumeClick(view: View) { + player.resume() + } + + fun onCapture(view: View) { + player.capture { + Toast.makeText(this, "capture ok", Toast.LENGTH_SHORT).show() + } + } + + fun onRecord(view: View) { + player.record(10 * 1000) { + Toast.makeText(this, "" + it, Toast.LENGTH_SHORT).show() + } + } + + fun onVolume(view: View) { + player.setVolume(0.0f) + } +} \ No newline at end of file diff --git a/webrtc_player/android/app/src/main/java/com/top/player/PusherDemoActivity.kt b/webrtc_player/android/app/src/main/java/com/top/player/PusherDemoActivity.kt new file mode 100644 index 00000000..168dafe5 --- /dev/null +++ b/webrtc_player/android/app/src/main/java/com/top/player/PusherDemoActivity.kt @@ -0,0 +1,97 @@ +package com.top.player + +import android.Manifest +import android.content.Intent +import android.os.Bundle +import android.view.View +import android.widget.Toast +import androidx.appcompat.app.AppCompatActivity +import com.permissionx.guolindev.PermissionX +import com.rtc.core.RTCSurfaceView +import com.rtc.core.ZLMRTCPusher +import com.rtc.core.push.PushMode +import com.rtc.core.push.ZLMRTCPusherImpl +import com.top.player.databinding.ActivityPlayerBinding +import com.top.player.databinding.ActivityPusherBinding + + +class PusherDemoActivity : AppCompatActivity() { + + + private val pusher: ZLMRTCPusher by lazy { + ZLMRTCPusherImpl(this) + } + + + private val binding by lazy { + ActivityPusherBinding.inflate(layoutInflater) + } + + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + setContentView(R.layout.activity_pusher) + + val rtcSurfaceView = findViewById(R.id.surface_view_render) + + pusher.bind(rtcSurfaceView, true) + setTitle("Pusher Demo") + + + pusher.setOnErrorListener { code, msg -> + Toast.makeText(this, "code:${code},msg:${msg}", Toast.LENGTH_SHORT).show() + } + + } + + fun onPushCamera(view: View) { + PermissionX.init(this) + .permissions(Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO) + .request { allGranted, grantedList, deniedList -> + if (allGranted) { + pusher.push(binding.tvApp.text.toString(), binding.tvStreamId.text.toString()) + } + } + } + + fun onPushScreen(view: View) { + PermissionX.init(this) + .permissions(Manifest.permission.RECORD_AUDIO) + .request { allGranted, grantedList, deniedList -> + if (allGranted) { + pusher.push( + binding.tvApp.text.toString(), + binding.tvStreamId.text.toString(), + PushMode.SCREEN + ) + } + } + } + + fun onPushFile(view: View) { + PermissionX.init(this) + .permissions(Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE) + .request { allGranted, grantedList, deniedList -> + if (allGranted) { + pusher.push( + binding.tvApp.text.toString(), + binding.tvStreamId.text.toString(), + PushMode.FILE, + "" + ) + } + } + } + + override fun onDestroy() { + super.onDestroy() + pusher.stop() + } + + fun onStopPush(view: View) { + pusher.stop() + } + + +} \ No newline at end of file diff --git a/webrtc_player/android/app/src/main/java/com/zlmediakit/webrtc/MainActivity.kt b/webrtc_player/android/app/src/main/java/com/zlmediakit/webrtc/MainActivity.kt deleted file mode 100644 index 15a8efc8..00000000 --- a/webrtc_player/android/app/src/main/java/com/zlmediakit/webrtc/MainActivity.kt +++ /dev/null @@ -1,79 +0,0 @@ -package com.zlmediakit.webrtc - -import android.annotation.SuppressLint -import android.graphics.drawable.BitmapDrawable -import android.graphics.drawable.Drawable -import android.os.Bundle -import android.widget.Toast -import androidx.appcompat.app.AppCompatActivity -import kotlinx.android.synthetic.main.activity_main.* -import kotlinx.android.synthetic.main.activity_main.view.* - - -class MainActivity : AppCompatActivity() { - - private var isSpeaker = true - - @SuppressLint("SetTextI18n") - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.activity_main) - - lifecycle.addObserver(web_rtc_sv) - - //http://124.223.98.45/index/api/webrtc?app=live&stream=test&type=play - url.setText("http://124.223.98.45/index/api/webrtc?app=live&stream=test&type=play") - - //http://192.168.1.17/index/api/webrtc?app=live&stream=test&type=play - btn_play.setOnClickListener { - web_rtc_sv?.setVideoPath(url.text.toString()) - web_rtc_sv.start() - } - - web_rtc_sv.setOnErrorListener { errorCode, errorMsg -> - runOnUiThread { - Toast.makeText(this, "errorCode:$errorCode,errorMsg:$errorMsg", Toast.LENGTH_SHORT) - .show() - } - } - - - btn_pause.setOnClickListener { - web_rtc_sv?.pause() - } - - btn_resume.setOnClickListener { - web_rtc_sv?.resume() - } - - btn_screenshot.setOnClickListener { - web_rtc_sv?.screenshot { - runOnUiThread { - iv_screen.setImageDrawable(BitmapDrawable(it)) - } - } - } - - btn_mute.setOnClickListener { - web_rtc_sv.mute(true) - } - - - selectAudio() - btn_speaker.setOnClickListener { - selectAudio() - } - - } - - fun selectAudio(){ - if (isSpeaker){ - btn_speaker.setText("扬声器") - web_rtc_sv.setSpeakerphoneOn(isSpeaker) - }else{ - btn_speaker.setText("话筒") - web_rtc_sv.setSpeakerphoneOn(isSpeaker) - } - isSpeaker=!isSpeaker - } -} \ No newline at end of file diff --git a/webrtc_player/android/app/src/main/java/com/zlmediakit/webrtc/WebRTCSurfaceView.kt b/webrtc_player/android/app/src/main/java/com/zlmediakit/webrtc/WebRTCSurfaceView.kt deleted file mode 100644 index 3e94171c..00000000 --- a/webrtc_player/android/app/src/main/java/com/zlmediakit/webrtc/WebRTCSurfaceView.kt +++ /dev/null @@ -1,439 +0,0 @@ -package com.zlmediakit.webrtc - -import android.content.Context -import android.graphics.Bitmap -import android.media.AudioManager -import android.util.AttributeSet -import android.util.Log -import android.view.LayoutInflater -import android.widget.RelativeLayout -import androidx.lifecycle.DefaultLifecycleObserver -import androidx.lifecycle.LifecycleOwner -import com.google.gson.Gson -import okhttp3.* -import okhttp3.MediaType.Companion.toMediaType -import okhttp3.MediaType.Companion.toMediaTypeOrNull -import org.webrtc.* -import org.webrtc.RendererCommon.ScalingType -import org.webrtc.audio.AudioDeviceModule -import org.webrtc.audio.JavaAudioDeviceModule -import java.io.IOException -import java.util.* - -public class WebRTCSurfaceView(context: Context, attrs: AttributeSet?) : - RelativeLayout(context, attrs), DefaultLifecycleObserver, RendererCommon.RendererEvents { - - - private data class sdp(var sdp: String, var username: String, var password: String) - - private data class SdpResponse(var code: Int, var id: String, var sdp: String, var type: String) - - private enum class ErrorCode(val errorCode: Int) { - SUCCESS(0x00), - GET_REMOTE_SDP_ERROR(0x01); - } - - - companion object { - private val TAG = "WebRTCSurfaceView" - - } - - private var mContext: Context = context - - private val eglBase: EglBase = EglBase.create() - private var mEGLBaseContext: EglBase.Context = eglBase.eglBaseContext - - private lateinit var videoUrl: String; - - private var mPeerConnectionFactory: PeerConnectionFactory? = null - - private var mLocalMediaStream: MediaStream? = null - private var mLocalAudioTrack: AudioTrack? = null - private var mAudioSource: AudioSource? = null - - private var mLocalSessionDescription: SessionDescription? = null - private var mRemoteSessionDescription: SessionDescription? = null - - private var mLocalPeer: Peer? = null - - private var mSurfaceViewRenderer: SurfaceViewRenderer - - private lateinit var OnErrorListener: (errorCode: Int, errorMsg: String) -> Unit? - - fun setOnErrorListener(listener: (errorCode: Int, errorMsg: String) -> Unit) { - this.OnErrorListener = listener - } - - private lateinit var OnPreparedListener: () -> Unit? - - fun setOnPreparedListener(listener: () -> Unit) { - this.OnPreparedListener = listener - } - - private val audioManager: AudioManager - - - init { - - val view = LayoutInflater.from(mContext).inflate(R.layout.layout_videoview, this) - - mPeerConnectionFactory = createConnectionFactory() - - mSurfaceViewRenderer = view.findViewById(R.id.surface_view_renderer) - - mSurfaceViewRenderer.init(mEGLBaseContext, this) - mSurfaceViewRenderer.setScalingType(ScalingType.SCALE_ASPECT_FILL) - mSurfaceViewRenderer.setEnableHardwareScaler(true) - - - //创建媒体流 - mLocalMediaStream = mPeerConnectionFactory?.createLocalMediaStream("ARDAMS") - //采集音频 - mAudioSource = mPeerConnectionFactory?.createAudioSource(createAudioConstraints()) - mLocalAudioTrack = mPeerConnectionFactory?.createAudioTrack("ARDAMSa0", mAudioSource) - - //添加Tracks - mLocalMediaStream?.addTrack(mLocalAudioTrack) - - audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager - audioManager.isSpeakerphoneOn = false - - - } - - - private fun set(width: Int, height: Int) { - layoutParams.width = width - layoutParams.height = height - } - - private fun createConnectionFactory(): PeerConnectionFactory? { - - val options = PeerConnectionFactory.InitializationOptions.builder(mContext) - .setEnableInternalTracer(false) - .createInitializationOptions() - - PeerConnectionFactory.initialize(options) - - val videoEncoderFactory = DefaultVideoEncoderFactory( - mEGLBaseContext, - true, - true - ) - - val videoDecoderFactory = DefaultVideoDecoderFactory(mEGLBaseContext) - - - val audioDevice = createJavaAudioDevice() - val peerConnectionFactory = PeerConnectionFactory.builder() - .setAudioDeviceModule(audioDevice) - .setVideoEncoderFactory(videoEncoderFactory) - .setVideoDecoderFactory(videoDecoderFactory) - .createPeerConnectionFactory() - audioDevice.release() - - return peerConnectionFactory - - } - - private fun createAudioConstraints(): MediaConstraints { - val audioConstraints = MediaConstraints() - audioConstraints.mandatory.add( - MediaConstraints.KeyValuePair( - "googEchoCancellation", - "true" - ) - ) - audioConstraints.mandatory.add( - MediaConstraints.KeyValuePair( - "googAutoGainControl", - "false" - ) - ) - audioConstraints.mandatory.add( - MediaConstraints.KeyValuePair( - "googHighpassFilter", - "true" - ) - ) - audioConstraints.mandatory.add( - MediaConstraints.KeyValuePair( - "googNoiseSuppression", - "true" - ) - ) - return audioConstraints - } - - private fun offerOrAnswerConstraint(): MediaConstraints { - val mediaConstraints = MediaConstraints() - val keyValuePairs = java.util.ArrayList() - keyValuePairs.add(MediaConstraints.KeyValuePair("OfferToReceiveAudio", "true")) - keyValuePairs.add(MediaConstraints.KeyValuePair("OfferToReceiveVideo", "true")) - mediaConstraints.mandatory.addAll(keyValuePairs) - return mediaConstraints - } - - private fun createJavaAudioDevice(): AudioDeviceModule { - val audioTrackErrorCallback: JavaAudioDeviceModule.AudioTrackErrorCallback = object : - JavaAudioDeviceModule.AudioTrackErrorCallback { - override fun onWebRtcAudioTrackInitError(errorMessage: String) { - Log.i(TAG, "onWebRtcAudioTrackInitError ============> $errorMessage") - - } - - override fun onWebRtcAudioTrackStartError( - errorCode: JavaAudioDeviceModule.AudioTrackStartErrorCode, errorMessage: String - ) { - Log.i(TAG, "onWebRtcAudioTrackStartError ============> $errorCode:$errorMessage") - - } - - override fun onWebRtcAudioTrackError(errorMessage: String) { - Log.i(TAG, "onWebRtcAudioTrackError ============> $errorMessage") - - } - } - - - // Set audio track state callbacks. - val audioTrackStateCallback: JavaAudioDeviceModule.AudioTrackStateCallback = object : - JavaAudioDeviceModule.AudioTrackStateCallback { - override fun onWebRtcAudioTrackStart() { - Log.i(TAG, "onWebRtcAudioTrackStart ============>") - - } - - override fun onWebRtcAudioTrackStop() { - Log.i(TAG, "onWebRtcAudioTrackStop ============>") - - } - } - - return JavaAudioDeviceModule.builder(mContext) - .setUseHardwareAcousticEchoCanceler(true) - .setUseHardwareNoiseSuppressor(true) - .setAudioTrackErrorCallback(audioTrackErrorCallback) - .setAudioTrackStateCallback(audioTrackStateCallback) - .setUseStereoOutput(true) //立体声 - .createAudioDeviceModule() - } - - fun setVideoPath(url: String) { - videoUrl = url - } - - fun start() { - - mLocalPeer = Peer { - val okHttpClient = OkHttpClient.Builder().build() - - - val body = RequestBody.create("text/plain; charset=utf-8".toMediaType(), it!!) - - - val request: Request = Request.Builder() - .url(videoUrl) - .post(body) - .build() - - val call: Call = okHttpClient.newCall(request) - - call.enqueue(object : Callback { - override fun onFailure(call: Call, e: IOException) { - Log.i(TAG, "onFailure") - OnErrorListener?.invoke( - ErrorCode.GET_REMOTE_SDP_ERROR.errorCode, - e.message.toString() - ) - } - - override fun onResponse(call: Call, response: Response) { - val body = response.body?.string() - val sdpResponse = Gson().fromJson(body, SdpResponse::class.java) - - try { - mRemoteSessionDescription = SessionDescription( - SessionDescription.Type.fromCanonicalForm("answer"), - sdpResponse.sdp - ) - Log.i( - TAG, - "RemoteSdpObserver onCreateSuccess:[SessionDescription[type=${mRemoteSessionDescription?.type?.name},description=${mRemoteSessionDescription?.description}]]" - ) - mLocalPeer?.setRemoteDescription(mRemoteSessionDescription!!) - } catch (e: Exception) { - Log.i(TAG, e.toString()) - OnErrorListener.invoke( - ErrorCode.GET_REMOTE_SDP_ERROR.errorCode, - e.localizedMessage - ) - } - } - }) - } - } - - fun pause() { - mSurfaceViewRenderer.pauseVideo() - //mSurfaceViewRenderer.disableFpsReduction() - } - - fun resume() { - mSurfaceViewRenderer.setFpsReduction(15f) - } - - fun screenshot(listener: (bitmap: Bitmap) -> Unit) { - mSurfaceViewRenderer.addFrameListener({ - listener.invoke(it) - }, 1f) - } - - fun setSpeakerphoneOn(on: Boolean) { - audioManager.isSpeakerphoneOn = on - } - - fun mute(on:Boolean) { - audioManager.isMicrophoneMute=on - } - - override fun onDestroy(owner: LifecycleOwner) { - super.onDestroy(owner) - mSurfaceViewRenderer.release() - mLocalPeer?.mPeerConnection?.dispose() - mAudioSource?.dispose() - mPeerConnectionFactory?.dispose() - } - - override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec) - - } - - inner class Peer(var sdp: (String?) -> Unit = {}) : PeerConnection.Observer, SdpObserver { - - var mPeerConnection: PeerConnection? = null - - init { - mPeerConnection = createPeerConnection() - mPeerConnection?.createOffer(this, offerOrAnswerConstraint()) - } - - //初始化 RTCPeerConnection 连接管道 - private fun createPeerConnection(): PeerConnection? { - if (mPeerConnectionFactory == null) { - mPeerConnectionFactory = createConnectionFactory() - } - // 管道连接抽象类实现方法 - val ICEServers = LinkedList() - val rtcConfig = PeerConnection.RTCConfiguration(ICEServers) - //修改模式 PlanB无法使用仅接收音视频的配置 - //rtcConfig.sdpSemantics = PeerConnection.SdpSemantics.PLAN_B - return mPeerConnectionFactory?.createPeerConnection(rtcConfig, this) - } - - fun setRemoteDescription(sdp: SessionDescription) { - mPeerConnection?.setRemoteDescription(this, sdp) - } - - override fun onCreateSuccess(sessionDescription: SessionDescription?) { - mPeerConnection?.setLocalDescription(this, sessionDescription) - mPeerConnection?.addStream(mLocalMediaStream) - sdp.invoke(sessionDescription?.description) - } - - override fun onSetSuccess() { - - } - - override fun onCreateFailure(p0: String?) { - - } - - override fun onSetFailure(p0: String?) { - - } - - override fun onSignalingChange(signalingState: PeerConnection.SignalingState?) { - Log.i(TAG, "onSignalingChange ============> " + signalingState.toString()) - } - - override fun onIceConnectionChange(iceConnectionState: PeerConnection.IceConnectionState?) { - Log.i(TAG, "onIceConnectionChange ============> " + iceConnectionState.toString()) - - } - - override fun onIceConnectionReceivingChange(p0: Boolean) { - Log.i(TAG, "onIceConnectionReceivingChange ============> $p0") - - } - - override fun onIceGatheringChange(iceGatheringState: PeerConnection.IceGatheringState?) { - Log.i(TAG, "onIceGatheringChange ============> ${iceGatheringState.toString()}") - } - - override fun onIceCandidate(iceCandidate: IceCandidate?) { - Log.i(TAG, "onIceCandidate ============> ${iceCandidate.toString()}") - - - } - - override fun onIceCandidatesRemoved(p0: Array?) { - Log.i(TAG, "onIceCandidatesRemoved ============> ${p0.toString()}") - } - - override fun onAddStream(mediaStream: MediaStream?) { - Log.i(TAG, "onAddStream ============> ${mediaStream?.toString()}") - - if (mediaStream?.videoTracks?.isEmpty() != true) { - val remoteVideoTrack = mediaStream?.videoTracks?.get(0) - remoteVideoTrack?.setEnabled(true) - remoteVideoTrack?.addSink(mSurfaceViewRenderer) - } - - if (mediaStream?.audioTracks?.isEmpty() != true) { - val remoteAudioTrack = mediaStream?.audioTracks?.get(0) - remoteAudioTrack?.setEnabled(true) - remoteAudioTrack?.setVolume(1.0) - } - - - } - - override fun onRemoveStream(mediaStream: MediaStream?) { - Log.i(TAG, "onRemoveStream ============> ${mediaStream.toString()}") - - } - - override fun onDataChannel(dataChannel: DataChannel?) { - Log.i(TAG, "onDataChannel ============> ${dataChannel.toString()}") - - } - - override fun onRenegotiationNeeded() { - Log.i(TAG, "onRenegotiationNeeded ============>") - - } - - override fun onAddTrack(rtpReceiver: RtpReceiver?, p1: Array?) { - Log.i(TAG, "onAddTrack ============>" + rtpReceiver?.track()) - Log.i(TAG, "onAddTrack ============>" + p1?.size) - - } - } - - override fun onFirstFrameRendered() { - Log.i(TAG, "onFirstFrameRendered ============>") - - } - - override fun onFrameResolutionChanged(frameWidth: Int, frameHeight: Int, rotation: Int) { - Log.i(TAG, "onFrameResolutionChanged ============> $frameWidth:$frameHeight:$rotation") - //set(frameWidth,frameHeight) - } - - - - -} \ No newline at end of file diff --git a/webrtc_player/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/webrtc_player/android/app/src/main/res/drawable/ic_launcher_foreground.xml similarity index 100% rename from webrtc_player/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml rename to webrtc_player/android/app/src/main/res/drawable/ic_launcher_foreground.xml diff --git a/webrtc_player/android/app/src/main/res/layout/activity_main.xml b/webrtc_player/android/app/src/main/res/layout/activity_main.xml index fdefb4e5..afb6529b 100644 --- a/webrtc_player/android/app/src/main/res/layout/activity_main.xml +++ b/webrtc_player/android/app/src/main/res/layout/activity_main.xml @@ -1,93 +1,22 @@ - + android:orientation="vertical"> - - - - - + + - - - - - - - - - - - - - + android:onClick="toPushActivity" + android:text="推流" /> - - - - - - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/webrtc_player/android/app/src/main/res/layout/activity_player.xml b/webrtc_player/android/app/src/main/res/layout/activity_player.xml new file mode 100644 index 00000000..eebedc84 --- /dev/null +++ b/webrtc_player/android/app/src/main/res/layout/activity_player.xml @@ -0,0 +1,140 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/webrtc_player/android/app/src/main/res/layout/activity_pusher.xml b/webrtc_player/android/app/src/main/res/layout/activity_pusher.xml new file mode 100644 index 00000000..484ee730 --- /dev/null +++ b/webrtc_player/android/app/src/main/res/layout/activity_pusher.xml @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/webrtc_player/android/app/src/main/res/layout/layout_videoview.xml b/webrtc_player/android/app/src/main/res/layout/layout_videoview.xml deleted file mode 100644 index 43c56e5e..00000000 --- a/webrtc_player/android/app/src/main/res/layout/layout_videoview.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/webrtc_player/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/webrtc_player/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml index eca70cfe..6f3b755b 100644 --- a/webrtc_player/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ b/webrtc_player/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -2,4 +2,5 @@ + \ No newline at end of file diff --git a/webrtc_player/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/webrtc_player/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml index eca70cfe..6f3b755b 100644 --- a/webrtc_player/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ b/webrtc_player/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -2,4 +2,5 @@ + \ No newline at end of file diff --git a/webrtc_player/android/app/src/main/res/values-night/themes.xml b/webrtc_player/android/app/src/main/res/values-night/themes.xml index 6a2a7eac..79caf632 100644 --- a/webrtc_player/android/app/src/main/res/values-night/themes.xml +++ b/webrtc_player/android/app/src/main/res/values-night/themes.xml @@ -1,16 +1,7 @@ - \ No newline at end of file diff --git a/webrtc_player/android/app/src/main/res/values/colors.xml b/webrtc_player/android/app/src/main/res/values/colors.xml index f8c6127d..c8524cd9 100644 --- a/webrtc_player/android/app/src/main/res/values/colors.xml +++ b/webrtc_player/android/app/src/main/res/values/colors.xml @@ -1,10 +1,5 @@ - #FFBB86FC - #FF6200EE - #FF3700B3 - #FF03DAC5 - #FF018786 #FF000000 #FFFFFFFF \ No newline at end of file diff --git a/webrtc_player/android/app/src/main/res/values/strings.xml b/webrtc_player/android/app/src/main/res/values/strings.xml index a7484826..5fb2987c 100644 --- a/webrtc_player/android/app/src/main/res/values/strings.xml +++ b/webrtc_player/android/app/src/main/res/values/strings.xml @@ -1,3 +1,3 @@ - AndroidWebRTC + RTCPlayer \ No newline at end of file diff --git a/webrtc_player/android/app/src/main/res/values/themes.xml b/webrtc_player/android/app/src/main/res/values/themes.xml index 119a9df9..df2c41fa 100644 --- a/webrtc_player/android/app/src/main/res/values/themes.xml +++ b/webrtc_player/android/app/src/main/res/values/themes.xml @@ -1,16 +1,9 @@ - + +