master 59542fab5f54 cached
132 files
1010.5 KB
318.4k tokens
177 symbols
1 requests
Download .txt
Showing preview only (1,063K chars total). Download the full file or copy to clipboard to get everything.
Repository: ezranbayantemur/react-native-rtmp-publisher
Branch: master
Commit: 59542fab5f54
Files: 132
Total size: 1010.5 KB

Directory structure:
gitextract_iogv7721/

├── .editorconfig
├── .gitattributes
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.yml
│   │   └── feature_request.md
│   └── workflows/
│       └── build.yml
├── .gitignore
├── .husky/
│   ├── .npmignore
│   ├── commit-msg
│   └── pre-commit
├── .yarnrc
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── __mocks__/
│   └── RTMPPublisher.js
├── android/
│   ├── build.gradle
│   ├── gradle/
│   │   └── wrapper/
│   │       ├── gradle-wrapper.jar
│   │       └── gradle-wrapper.properties
│   ├── gradlew
│   ├── gradlew.bat
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           └── java/
│               └── com/
│                   └── reactnativertmppublisher/
│                       ├── RTMPManager.java
│                       ├── RTMPModule.java
│                       ├── RTMPPackage.java
│                       ├── enums/
│                       │   ├── AudioInputType.java
│                       │   ├── BluetoothDeviceStatuses.java
│                       │   └── StreamState.java
│                       ├── interfaces/
│                       │   └── ConnectionListener.java
│                       ├── modules/
│                       │   ├── BluetoothDeviceConnector.java
│                       │   ├── ConnectionChecker.java
│                       │   ├── Publisher.java
│                       │   └── SurfaceHolderHelper.java
│                       └── utils/
│                           └── ObjectCaster.java
├── babel.config.js
├── coverage/
│   ├── clover.xml
│   ├── coverage-final.json
│   ├── lcov-report/
│   │   ├── Component.tsx.html
│   │   ├── RTMPPublisher.tsx.html
│   │   ├── base.css
│   │   ├── block-navigation.js
│   │   ├── index.html
│   │   ├── prettify.css
│   │   ├── prettify.js
│   │   └── sorter.js
│   └── lcov.info
├── example/
│   ├── README.md
│   ├── android/
│   │   ├── app/
│   │   │   ├── build.gradle
│   │   │   ├── debug.keystore
│   │   │   ├── proguard-rules.pro
│   │   │   └── src/
│   │   │       ├── debug/
│   │   │       │   ├── AndroidManifest.xml
│   │   │       │   └── java/
│   │   │       │       └── com/
│   │   │       │           └── example/
│   │   │       │               └── reactnativertmp/
│   │   │       │                   └── ReactNativeFlipper.java
│   │   │       └── main/
│   │   │           ├── AndroidManifest.xml
│   │   │           ├── java/
│   │   │           │   └── com/
│   │   │           │       └── example/
│   │   │           │           └── reactnativertmp/
│   │   │           │               ├── MainActivity.java
│   │   │           │               ├── MainApplication.java
│   │   │           │               └── newarchitecture/
│   │   │           │                   ├── MainApplicationReactNativeHost.java
│   │   │           │                   ├── components/
│   │   │           │                   │   └── MainComponentsRegistry.java
│   │   │           │                   └── modules/
│   │   │           │                       └── MainApplicationTurboModuleManagerDelegate.java
│   │   │           ├── jni/
│   │   │           │   ├── CMakeLists.txt
│   │   │           │   ├── MainApplicationModuleProvider.cpp
│   │   │           │   ├── MainApplicationModuleProvider.h
│   │   │           │   ├── MainApplicationTurboModuleManagerDelegate.cpp
│   │   │           │   ├── MainApplicationTurboModuleManagerDelegate.h
│   │   │           │   ├── MainComponentsRegistry.cpp
│   │   │           │   ├── MainComponentsRegistry.h
│   │   │           │   └── OnLoad.cpp
│   │   │           └── res/
│   │   │               ├── drawable/
│   │   │               │   └── rn_edit_text_material.xml
│   │   │               └── values/
│   │   │                   ├── strings.xml
│   │   │                   └── styles.xml
│   │   ├── build.gradle
│   │   ├── gradle/
│   │   │   └── wrapper/
│   │   │       ├── gradle-wrapper.jar
│   │   │       └── gradle-wrapper.properties
│   │   ├── gradle.properties
│   │   ├── gradlew
│   │   ├── gradlew.bat
│   │   └── settings.gradle
│   ├── app.json
│   ├── babel.config.js
│   ├── index.tsx
│   ├── ios/
│   │   ├── .xcode.env
│   │   ├── File.swift
│   │   ├── Podfile
│   │   ├── RtmpExample/
│   │   │   ├── AppDelegate.h
│   │   │   ├── AppDelegate.mm
│   │   │   ├── Images.xcassets/
│   │   │   │   ├── AppIcon.appiconset/
│   │   │   │   │   └── Contents.json
│   │   │   │   └── Contents.json
│   │   │   ├── Info.plist
│   │   │   ├── LaunchScreen.storyboard
│   │   │   └── main.m
│   │   ├── RtmpExample-Bridging-Header.h
│   │   ├── RtmpExample.xcodeproj/
│   │   │   ├── project.pbxproj
│   │   │   └── xcshareddata/
│   │   │       └── xcschemes/
│   │   │           └── RtmpExample.xcscheme
│   │   ├── RtmpExample.xcworkspace/
│   │   │   ├── contents.xcworkspacedata
│   │   │   └── xcshareddata/
│   │   │       └── IDEWorkspaceChecks.plist
│   │   ├── assets/
│   │   │   └── app.json
│   │   └── main.jsbundle
│   ├── metro.config.js
│   ├── package.json
│   └── src/
│       ├── App.styles.tsx
│       ├── App.tsx
│       ├── components/
│       │   ├── Button/
│       │   │   ├── Button.styles.tsx
│       │   │   ├── Button.tsx
│       │   │   └── index.ts
│       │   ├── LiveBadge/
│       │   │   ├── LiveBadge.styles.tsx
│       │   │   ├── LiveBadge.tsx
│       │   │   └── index.ts
│       │   └── MicrophoneSelectModal/
│       │       ├── MicrophoneSelectModal.styles.tsx
│       │       ├── MicrophoneSelectModal.tsx
│       │       └── index.ts
│       └── hooks/
│           └── usePermissions.ts
├── ios/
│   ├── Podfile
│   ├── RTMPCreator.swift
│   ├── RTMPManager/
│   │   ├── RTMPView.swift
│   │   ├── RTMPViewManager.m
│   │   └── RTMPViewManager.swift
│   ├── RTMPModule/
│   │   ├── RTMPModule.m
│   │   └── RTMPModule.swift
│   ├── RtmpPublish-Bridging-Header.h
│   ├── RtmpPublish.xcodeproj/
│   │   └── project.pbxproj
│   └── RtmpPublish.xcworkspace/
│       ├── contents.xcworkspacedata
│       └── xcshareddata/
│           └── IDEWorkspaceChecks.plist
├── jest.config.js
├── package.json
├── react-native-rtmp-publisher.podspec
├── scripts/
│   └── bootstrap.js
├── src/
│   ├── Component.tsx
│   ├── RTMPPublisher.tsx
│   ├── index.tsx
│   ├── test/
│   │   ├── RTMPPublisher.test.tsx
│   │   └── __snapshots__/
│   │       └── RTMPPublisher.test.tsx.snap
│   └── types.ts
├── tsconfig.build.json
└── tsconfig.json

================================================
FILE CONTENTS
================================================

================================================
FILE: .editorconfig
================================================
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# editorconfig.org

root = true

[*]

indent_style = space
indent_size = 2

end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true


================================================
FILE: .gitattributes
================================================
*.pbxproj -text
# specific for windows script files
*.bat text eol=crlf

================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.yml
================================================
name: Bug Report
description: File a bug report
body:
  - type: textarea
    id: describe-the-bug
    attributes:
      label: Describe the bug
      description: A clear and concise description of what the bug is.
    validations:
      required: true
  - type: textarea
    id: to-reproduce
    attributes:
      label: To Reproduce
      description: Steps to reproduce the behavior
      placeholder: |
        1. Go to '...'
        2. Click on '....'
        3. Scroll down to '....'
        4. See error
    validations:
      required: true
  - type: textarea
    id: expected-behavior
    attributes:
      label: Expected behavior
      description: Steps to reproduce the behavior
    validations:
      required: true
  - type: textarea
    id: version
    attributes:
      label: Version
      description: What version of our software are you running?
    validations:
      required: true
  - type: textarea
    id: smartphone-info
    attributes:
      label: Smartphone info.
      description: please complete the following information
      placeholder: |
       - Device: [e.g. iPhone6]
       - OS: [e.g. iOS8.1]
  - type: textarea
    id: addditional-context
    attributes:
      label: Additional context
      description: Add any other context about the problem here.
  - type: textarea
    id: screenshot
    attributes:
      label: Screenshots
      description: If applicable, add screenshots to help explain your problem.
  - type: textarea
    id: logs
    attributes:
      label: Relevant log output
      description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
      render: shell

================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.


================================================
FILE: .github/workflows/build.yml
================================================
name: Build

on:
  pull_request:
    branches:
      - master
      - dev

jobs:
  build_dependency:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3

      - name: Caching node_modules
        id: cache-npm
        uses: actions/cache@v3
        env:
          cache-name: cache-node-modules
        with:
          path: ./node_modules
          key: rtmp-build-${{ env.cache-name }}-${{ hashFiles('**/yarn.lock') }}

      - name: Caching Pods
        id: cache-pods
        uses: actions/cache@v3
        env:
          cache-name: cache-cocoapods
        with:
          path: ./example/ios/Pods
          key: rtmp-build-${{ env.cache-name }}-${{ hashFiles('./example/ios/Podfile.lock') }}

      - name: Install dependencies
        run: |
          yarn
      - name: Lint files
        run: |
          yarn lint
      - name: Typescript checking
        run: |
          yarn typescript
      - name: Unit tests
        run: |
          yarn test --coverage --updateSnapshot --verbose
      - name: Building the package
        run: |
          yarn prepare
  build_android:
    needs: build_dependency
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3

      - name: Caching node_modules
        id: cache-npm
        uses: actions/cache@v3
        env:
          cache-name: cache-node-modules
        with:
          path: ./node_modules
          key: rtmp-build-${{ env.cache-name }}-${{ hashFiles('**/yarn.lock') }}

      - name: Install dependencies
        run: |
          yarn
      - name: Caching Gradle
        id: cache-gradle
        uses: actions/cache@v3
        env:
          cache-name: cache-gradle-files
        with:
          path: ./example/android/.gradle
          key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('./example/android/gradle/wrapper/gradle-wrapper.properties') }}
          restore-keys: |
            ${{ runner.os }}-build-${{ env.cache-name }}-
      - name: Install dependencies
        run: |
          yarn
      - name: Building Android
        run: |
          cd example/android && ./gradlew build
  build_ios:
    needs: build_dependency
    runs-on: macos-latest

    steps:
      - uses: actions/checkout@v3

      - name: Caching node_modules
        id: cache-npm
        uses: actions/cache@v3
        env:
          cache-name: cache-node-modules
        with:
          path: ./node_modules
          key: rtmp-build-${{ env.cache-name }}-${{ hashFiles('**/yarn.lock') }}

      - name: Caching Pods
        id: cache-pods
        uses: actions/cache@v3
        env:
          cache-name: cache-cocoapods
        with:
          path: ./example/ios/Pods
          key: rtmp-build-${{ env.cache-name }}-${{ hashFiles('./example/ios/Podfile.lock') }}

      - name: Install dependencies
        run: |
          yarn
      - name: Building iOS
        run: |
          cd example/ios && xcodebuild -quiet -workspace RtmpExample.xcworkspace -scheme RtmpExample -destination generic/platform=iOS CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO build


================================================
FILE: .gitignore
================================================
# OSX
#
.DS_Store

# XDE
.expo/

# VSCode
.vscode/
jsconfig.json

# Xcode
#
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
*.xccheckout
*.moved-aside
DerivedData
*.hmap
*.ipa
*.xcuserstate
project.xcworkspace

# Android/IJ
#
.classpath
.cxx
.gradle
.idea
.project
.settings
local.properties
android.iml

# Cocoapods
#
example/ios/Pods
/ios/Pods

# node.js
#
node_modules/
npm-debug.log
yarn-debug.log
yarn-error.log

# BUCK
buck-out/
\.buckd/
android/app/libs
android/keystores/debug.keystore

# Expo
.expo/*

# generated by bob
lib/
example/.env
.env


================================================
FILE: .husky/.npmignore
================================================
_


================================================
FILE: .husky/commit-msg
================================================
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

yarn commitlint -E HUSKY_GIT_PARAMS


================================================
FILE: .husky/pre-commit
================================================
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

yarn lint && yarn typescript


================================================
FILE: .yarnrc
================================================
# Override Yarn command so we can automatically setup the repo on running `yarn`

yarn-path "scripts/bootstrap.js"


================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct

## Our Pledge

We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.

We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.

## Our Standards

Examples of behavior that contributes to a positive environment for our
community include:

* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
  and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
  overall community

Examples of unacceptable behavior include:

* The use of sexualized language or imagery, and sexual attention or
  advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
  address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
  professional setting

## Enforcement Responsibilities

Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.

Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.

## Scope

This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
.
All complaints will be reviewed and investigated promptly and fairly.

All community leaders are obligated to respect the privacy and security of the
reporter of any incident.

## Enforcement Guidelines

Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:

### 1. Correction

**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.

**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.

### 2. Warning

**Community Impact**: A violation through a single incident or series
of actions.

**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.

### 3. Temporary Ban

**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.

**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.

### 4. Permanent Ban

**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior,  harassment of an
individual, or aggression toward or disparagement of classes of individuals.

**Consequence**: A permanent ban from any sort of public interaction within
the community.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.

Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).

[homepage]: https://www.contributor-covenant.org

For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing

We want this community to be friendly and respectful to each other. Please follow it in all your interactions with the project.

## Development workflow

To get started with the project, run `yarn` in the root directory to install the required dependencies for each package:

```sh
yarn
```

> While it's possible to use [`npm`](https://github.com/npm/cli), the tooling is built around [`yarn`](https://classic.yarnpkg.com/), so you'll have an easier time if you use `yarn` for development.

While developing, you can run the [example app](/example/) to test your changes. Any changes you make in your library's JavaScript code will be reflected in the example app without a rebuild. If you change any native code, then you'll need to rebuild the example app.

To start the packager:

```sh
yarn example start
```

To run the example app on Android:

```sh
yarn example android
```

To run the example app on iOS:

```sh
yarn example ios
```

Make sure your code passes TypeScript and ESLint. Run the following to verify:

```sh
yarn typescript
yarn lint
```

To fix formatting errors, run the following:

```sh
yarn lint --fix
```

Remember to add tests for your change if possible. Run the unit tests by:

```sh
yarn test
```

To edit the Objective-C files, open `example/ios/RtmpPublisherExample.xcworkspace` in XCode and find the source files at `Pods > Development Pods > react-native-rtmp-publisher`.

To edit the Kotlin files, open `example/android` in Android studio and find the source files at `reactnativertmppublisher` under `Android`.

### Commit message convention

We follow the [conventional commits specification](https://www.conventionalcommits.org/en) for our commit messages:

- `fix`: bug fixes, e.g. fix crash due to deprecated method.
- `feat`: new features, e.g. add new method to the module.
- `refactor`: code refactor, e.g. migrate from class components to hooks.
- `docs`: changes into documentation, e.g. add usage example for the module..
- `test`: adding or updating tests, e.g. add integration tests using detox.
- `chore`: tooling changes, e.g. change CI config.

Our pre-commit hooks verify that your commit message matches this format when committing.

### Linting and tests

[ESLint](https://eslint.org/), [Prettier](https://prettier.io/), [TypeScript](https://www.typescriptlang.org/)

We use [TypeScript](https://www.typescriptlang.org/) for type checking, [ESLint](https://eslint.org/) with [Prettier](https://prettier.io/) for linting and formatting the code, and [Jest](https://jestjs.io/) for testing.

Our pre-commit hooks verify that the linter and tests pass when committing.

### Publishing to npm

We use [release-it](https://github.com/release-it/release-it) to make it easier to publish new versions. It handles common tasks like bumping version based on semver, creating tags and releases etc.

To publish new versions, run the following:

```sh
yarn release
```

### Scripts

The `package.json` file contains various scripts for common tasks:

- `yarn bootstrap`: setup project by installing all dependencies and pods.
- `yarn typescript`: type-check files with TypeScript.
- `yarn lint`: lint files with ESLint.
- `yarn test`: run unit tests with Jest.
- `yarn example start`: start the Metro server for the example app.
- `yarn example android`: run the example app on Android.
- `yarn example ios`: run the example app on iOS.

### Sending a pull request

> **Working on your first pull request?** You can learn how from this _free_ series: [How to Contribute to an Open Source Project on GitHub](https://app.egghead.io/playlists/how-to-contribute-to-an-open-source-project-on-github).

When you're sending a pull request:

- Prefer small pull requests focused on one change.
- Verify that linters and tests are passing.
- Review the documentation to make sure it looks good.
- Follow the pull request template when opening a pull request.
- For pull requests that change the API or implementation, discuss with maintainers first by opening an issue.

## Code of Conduct

### Our Pledge

We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.

We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.

### Our Standards

Examples of behavior that contributes to a positive environment for our community include:

- Demonstrating empathy and kindness toward other people
- Being respectful of differing opinions, viewpoints, and experiences
- Giving and gracefully accepting constructive feedback
- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
- Focusing on what is best not just for us as individuals, but for the overall community

Examples of unacceptable behavior include:

- The use of sexualized language or imagery, and sexual attention or
  advances of any kind
- Trolling, insulting or derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or email
  address, without their explicit permission
- Other conduct which could reasonably be considered inappropriate in a
  professional setting

### Enforcement Responsibilities

Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.

Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.

### Scope

This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.

### Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at [INSERT CONTACT METHOD]. All complaints will be reviewed and investigated promptly and fairly.

All community leaders are obligated to respect the privacy and security of the reporter of any incident.

### Enforcement Guidelines

Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:

#### 1. Correction

**Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.

**Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.

#### 2. Warning

**Community Impact**: A violation through a single incident or series of actions.

**Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.

#### 3. Temporary Ban

**Community Impact**: A serious violation of community standards, including sustained inappropriate behavior.

**Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.

#### 4. Permanent Ban

**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.

**Consequence**: A permanent ban from any sort of public interaction within the community.

### Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0,
available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.

Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity).

[homepage]: https://www.contributor-covenant.org

For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations.


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2021 Ezran

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
### ⚠️⚠️⚠️ THIS PACKAGE CURRENTLY UNMAINTENED. WILL RE-MAINTENED IN SOON WITH NEW ARCH ⚠️⚠️⚠️

<p align="center">
<img src="https://user-images.githubusercontent.com/42299721/200197084-5e8ebcf2-320e-49cf-8504-0ad94773c218.png" alt="logo" width="90%"/>

<p align="center">
<img src="https://img.shields.io/github/license/ezranbayantemur/react-native-rtmp-publisher" alt="github/license" />
<img src="https://img.shields.io/github/issues/ezranbayantemur/react-native-rtmp-publisher" alt="github/issues" />
<img src="https://img.shields.io/github/issues-pr/ezranbayantemur/react-native-rtmp-publisher" alt="github/issues-pr" />
<img src="https://img.shields.io/npm/dw/react-native-rtmp-publisher" alt="npm/dw" />
<img src="https://img.shields.io/github/followers/ezranbayantemur?style=social" alt="github/followers" />
<img src="https://img.shields.io/github/stars/ezranbayantemur/react-native-rtmp-publisher?style=social" alt="github/stars" />
<img src="https://img.shields.io/github/forks/ezranbayantemur/react-native-rtmp-publisher?style=social" alt="github/forks" />
</p>

📹 Live stream RTMP publisher for React Native with built in camera support!

## Installation

```sh
npm install react-native-rtmp-publisher
```

or

```sh
yarn add react-native-rtmp-publisher
```

and for iOS
```sh
cd ios && pod install
```
## Android

Add Android Permission for camera and audio to `AndroidManifest.xml`

```xml
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
```


## iOS

Add iOS Permission for camera and audio to `Info.plist`

```xml
<key>NSCameraUsageDescription</key>
 <string>CAMERA PERMISSION DESCRIPTION</string>
<key>NSMicrophoneUsageDescription</key>
 <string>AUDIO PERMISSION DESCRIPTION</string>
```

Implement these changes to `AppDelegate.m` (or `AppDelegate.mm`) 
```objc
#import <AVFoundation/AVFoundation.h> // <-- Add this import
.. 
.. 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  ..
  .. 
  ..
  ..

  // <-- Add this section -->
  AVAudioSession *session = AVAudioSession.sharedInstance;
  NSError *error = nil;

  if (@available(iOS 10.0, *)) {
      [session
        setCategory:AVAudioSessionCategoryPlayAndRecord
        mode:AVAudioSessionModeVoiceChat
        options:AVAudioSessionCategoryOptionDefaultToSpeaker|AVAudioSessionCategoryOptionAllowBluetooth
        error:&error];
    } else {
      SEL selector = NSSelectorFromString(@"setCategory:withOptions:error:");
      
      NSArray * optionsArray =
          [NSArray arrayWithObjects:
            [NSNumber numberWithInteger:AVAudioSessionCategoryOptionAllowBluetooth],
            [NSNumber numberWithInteger:AVAudioSessionCategoryOptionDefaultToSpeaker], nil];
      
      [session
        performSelector:selector
        withObject: AVAudioSessionCategoryPlayAndRecord
        withObject: optionsArray
      ];
      
      [session 
        setMode:AVAudioSessionModeVoiceChat 
        error:&error
      ];
    }
    
    [session 
      setActive:YES 
      error:&error
    ];
    // <-- Add this section -->

    return YES;
  }
```
## Example Project

Clone the repo and run

```sh
yarn
```
and

```sh
cd example && yarn ios (or yarn android)
```

You can use Youtube for live stream server. You can check [Live on Youtube](https://support.google.com/youtube/answer/2474026?hl=tr&ref_topic=9257984)

## Usage
```js
import RTMPPublisher from 'react-native-rtmp-publisher';

// ...

async function publisherActions() {
  await publisherRef.current.startStream();
  await publisherRef.current.stopStream();
  await publisherRef.current.mute();
  await publisherRef.current.unmute();
  await publisherRef.current.switchCamera();
  await publisherRef.current.getPublishURL();
  await publisherRef.current.isMuted();
  await publisherRef.current.isStreaming();
  await publisherRef.current.toggleFlash();
  await publisherRef.current.hasCongestion();
  await publisherRef.current.isAudioPrepared();
  await publisherRef.current.isVideoPrepared();
  await publisherRef.current.isCameraOnPreview();
  await publisherRef.current.setAudioInput(audioInput: AudioInputType);
}

<RTMPPublisher
  ref={publisherRef}
  streamURL="rtmp://your-publish-url"
  streamName="stream-name"
  onConnectionFailedRtmp={() => ...}
  onConnectionStartedRtmp={() => ...}
  onConnectionSuccessRtmp={() => ...}
  onDisconnectRtmp={() => ...}
  onNewBitrateRtmp={() => ...}
  onStreamStateChanged={(status: streamState) => ...}
/>
```

## Props

|     Name     |   Type   | Required |              Description              |
| :----------: | :------: | :------: | :-----------------------------------: |
| `streamURL`  | `string` |  `true`  | Publish URL address with RTM Protocol |
| `streamName` | `string` |  `true`  |          Stream name or key           |

### Youtube Example

For live stream, Youtube gives you stream url and stream key, you can place the key on `streamName` parameter

**Youtube Stream URL:** `rtmp://a.rtmp.youtube.com/live2`

**Youtube Stream Key:** `****-****-****-****-****`

```js
<RTMPPublisher
  streamURL="rtmp://a.rtmp.youtube.com/live2"
  streamName="****-****-****-****-****"
  ...
  ...
```

## Events

|          Name                    |        Returns            |                                        Description                                        |  Android | iOS |
| :------------------------------: | :-----------------------: | :---------------------------------------------------------------------------------------: | :------: |:---:|
|      `onConnectionFailed`        |         `null`            |                        Invokes on connection fails to publish URL                         |     ✅    |  ✅ |
|     `onConnectionStarted`        |         `null`            |                        Invokes on connection start to publish URL                         |     ✅    |  ✅ |
|     `onConnectionSuccess`        |         `null`            |                       Invokes on connection success to publish URL                        |     ✅    |  ✅ |
|         `onDisconnect`           |         `null`            |                          Invokes on disconnect from publish URL                           |     ✅    |  ✅ |
|     `onNewBitrateReceived`       |         `null`            |                         Invokes on new bitrate received from URL                          |     ✅    |  ❌ |
|     `onStreamStateChanged`       |      `StreamState`        | Invokes on stream state changes. It can be use alternatively for above connection events. |     ✅    |  ✅ |
| `onBluetoothDeviceStatusChanged` | `BluetoothDeviceStatuses` |                        Invokes on bluetooth headset state changes.                        |     ✅    |  ❌ |

## Methods

|        Name         |          Returns          |         Description         |   Android | iOS |
| :-----------------: | :------------------------:| :-------------------------: |  :------: |:---:|
|    `startStream`    |       `Promise<void>`     |      Starts the stream      |     ✅    |  ✅ |
|    `stopStream`     |       `Promise<void>`     |      Stops the stream       |     ✅    |  ✅ |
|       `mute`        |       `Promise<void>`     |    Mutes the microphone     |     ✅    |  ✅ |
|      `unmute`       |       `Promise<void>`     |   Unmutes the microphone    |     ✅    |  ✅ |
|   `switchCamera`    |       `Promise<void>`     |     Switches the camera     |     ✅    |  ✅ |
|   `toggleFlash`     |       `Promise<void>`     |    Toggles the flash        |     ✅    |  ✅ |
|   `getPublishURL`   |      `Promise<string>`    |    Gets the publish URL     |     ✅    |  ✅ |
|      `isMuted`      |      `Promise<boolean>`   |  Returns microphone state   |     ✅    |  ✅ |
|    `isStreaming`    |      `Promise<boolean>`   |   Returns streaming state   |     ✅    |  ✅ |
|   `hasCongestion`   |      `Promise<boolean>`   |    Returns if congestion    |     ✅    |  ❌ |
|  `isAudioPrepared`  |      `Promise<boolean>`   | Returns audio prepare state |     ✅    |  ✅ |
|  `isVideoPrepared`  |      `Promise<boolean>`   | Returns video prepare state |     ✅    |  ✅ |
| `isCameraOnPreview` |      `Promise<boolean>`   |    Returns camera is on     |     ✅    |  ❌ |
|   `setAudioInput`   |  `Promise<AudioInputType>`|    Sets microphone input    |     ✅    |  ✅ |

## Types

| Name                      |                      Value                          |
| ------------------------- | :--------------------------------------------------:|
| `streamState`             | `CONNECTING`, `CONNECTED`, `DISCONNECTED`, `FAILED` |
| `BluetoothDeviceStatuses` | `CONNECTING`, `CONNECTED`, `DISCONNECTED`           |
| `AudioInputType`          | `BLUETOOTH_HEADSET`, `SPEAKER`, `WIRED_HEADSET`     |

* AudioInputType: WIRED_HEADSET type supporting in only iOS. On Android it affects nothing. If a wired headset connected to Android device, device uses it as default.
## Used Native Packages

- Android: [rtmp-rtsp-stream-client-java](https://github.com/pedroSG94/rtmp-rtsp-stream-client-java) [2.2.2]
- iOS: [HaishinKit.swift](https://github.com/shogo4405/HaishinKit.swift) [1.2.7]

## Contributing

See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow.

## License

MIT


================================================
FILE: __mocks__/RTMPPublisher.js
================================================
import { NativeModules } from 'react-native';

NativeModules.RTMPPublisher = {
  startStream: jest.fn(),
  stopStream: jest.fn(),
  isStreaming: jest.fn(),
  isCameraOnPreview: jest.fn(),
  getPublishURL: jest.fn(),
  hasCongestion: jest.fn(),
  isAudioPrepared: jest.fn(),
  isVideoPrepared: jest.fn(),
  isMuted: jest.fn(),
  mute: jest.fn(),
  unmute: jest.fn(),
  switchCamera: jest.fn(),
  toggleFlash: jest.fn(),
};


================================================
FILE: android/build.gradle
================================================
buildscript {
  if (project == rootProject) {
    repositories {
      google()
      mavenCentral()
      jcenter()
    }

    dependencies {
      classpath 'com.android.tools.build:gradle:3.5.3'
    }
  }
}

apply plugin: 'com.android.library'

def safeExtGet(prop, fallback) {
  rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
}

android {
  compileSdkVersion safeExtGet('Rtmp_compileSdkVersion', 31)
  defaultConfig {
    minSdkVersion safeExtGet('Rtmp_minSdkVersion', 21)
    targetSdkVersion safeExtGet('Rtmp_targetSdkVersion', 31)
    versionCode 1
    versionName "1.0"

  }

  buildTypes {
    release {
      minifyEnabled false
    }
  }
  lintOptions {
    disable 'GradleCompatible'
  }
  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }
}

repositories {
  mavenLocal()
  maven {
    // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
    url("$rootDir/../node_modules/react-native/android")
  }
  google()
  mavenCentral()
  jcenter()
  maven { url 'https://www.jitpack.io' }
}

dependencies {
  //noinspection GradleDynamicVersion
  implementation fileTree(dir: 'libs', include: ['*.jar'])
  implementation 'com.github.pedroSG94.rtmp-rtsp-stream-client-java:rtplibrary:2.2.2'
  implementation "com.facebook.react:react-native:+"  // From node_modules
}


================================================
FILE: android/gradle/wrapper/gradle-wrapper.properties
================================================
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists


================================================
FILE: android/gradlew
================================================
#!/usr/bin/env sh

#
# Copyright 2015 the original author or 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
##
##############################################################################

# 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
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null

APP_NAME="Gradle"
APP_BASE_NAME=`basename "$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='"-Xmx64m" "-Xms64m"'

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"

warn () {
    echo "$*"
}

die () {
    echo
    echo "$*"
    echo
    exit 1
}

# 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
    ;;
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"
    else
        JAVACMD="$JAVA_HOME/bin/java"
    fi
    if [ ! -x "$JAVACMD" ] ; then
        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
    fi
else
    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
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 or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; 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=`expr $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" ;;
    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, 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"

exec "$JAVACMD" "$@"


================================================
FILE: android/gradlew.bat
================================================
@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
@rem  Gradle startup script for Windows
@rem
@rem ##########################################################################

@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal

set DIRNAME=%~dp0
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="-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 execute

echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe

if exist "%JAVA_EXE%" goto execute

echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

: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 %*

:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd

:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1

:mainEnd
if "%OS%"=="Windows_NT" endlocal

:omega


================================================
FILE: android/src/main/AndroidManifest.xml
================================================
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.reactnativertmppublisher">

    <uses-permission android:name="android.permission.BLUETOOTH" />
</manifest>


================================================
FILE: android/src/main/java/com/reactnativertmppublisher/RTMPManager.java
================================================
package com.reactnativertmppublisher;

import android.view.SurfaceView;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.facebook.react.common.MapBuilder;
import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.events.RCTEventEmitter;
import com.reactnativertmppublisher.modules.Publisher;
import com.reactnativertmppublisher.modules.SurfaceHolderHelper;

import java.util.Map;

public class RTMPManager extends SimpleViewManager<SurfaceView> {
  //TODO: "Do not place Android context classes in static fields (static reference to Publisher which has field _surfaceView pointing to SurfaceView); this is a memory leak"
  public static Publisher publisher;
  public final String REACT_CLASS_NAME = "RTMPPublisher";
  SurfaceView surfaceView;
  private ThemedReactContext _reactContext;

  View.OnLayoutChangeListener onLayoutChangeListener = new View.OnLayoutChangeListener() {
    @Override
    public void onLayoutChange(@NonNull View view, int i, int i1, int i2, int i3, int i4, int i5, int i6, int i7) {

    }
  };

  @NonNull
  @Override
  public String getName() {
    return REACT_CLASS_NAME;
  }

  @NonNull
  @Override
  protected SurfaceView createViewInstance(@NonNull ThemedReactContext reactContext) {
    _reactContext = reactContext;
    surfaceView = new SurfaceView(_reactContext);
    publisher = new Publisher(_reactContext, surfaceView);
    surfaceView.addOnLayoutChangeListener(onLayoutChangeListener);

    SurfaceHolderHelper surfaceHolderHelper = new SurfaceHolderHelper(_reactContext, publisher.getRtmpCamera(), surfaceView.getId());
    surfaceView.getHolder().addCallback(surfaceHolderHelper);

    return surfaceView;
  }

  @ReactProp(name = "streamURL")
  public void setStreamURL(SurfaceView surfaceView, @Nullable String url) {
    publisher.setStreamUrl(url);
  }

  @ReactProp(name = "streamName")
  public void setStreamName(SurfaceView surfaceView, @Nullable String name) {
    publisher.setStreamName(name);
  }

  @Nullable
  @Override
  public Map<String, Object> getExportedCustomDirectEventTypeConstants() {
    return MapBuilder.<String, Object>builder()
      .put("onDisconnect", MapBuilder.of("registrationName", "onDisconnect"))
      .put("onConnectionFailed", MapBuilder.of("registrationName", "onConnectionFailed"))
      .put("onConnectionStarted", MapBuilder.of("registrationName", "onConnectionStarted"))
      .put("onConnectionSuccess", MapBuilder.of("registrationName", "onConnectionSuccess"))
      .put("onNewBitrateReceived", MapBuilder.of("registrationName", "onNewBitrateReceived"))
      .put("onStreamStateChanged", MapBuilder.of("registrationName", "onStreamStateChanged"))
      .put("onBluetoothDeviceStatusChanged", MapBuilder.of("registrationName", "onBluetoothDeviceStatusChanged"))
      .build();
  }
}


================================================
FILE: android/src/main/java/com/reactnativertmppublisher/RTMPModule.java
================================================
package com.reactnativertmppublisher;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.reactnativertmppublisher.enums.AudioInputType;

public class RTMPModule extends ReactContextBaseJavaModule {
  private final String REACT_MODULE_NAME = "RTMPPublisher";

  public RTMPModule(@Nullable ReactApplicationContext reactContext) {
    super(reactContext);
  }

  @NonNull
  @Override
  public String getName() {
    return REACT_MODULE_NAME;
  }

  @ReactMethod
  public void isStreaming(Promise promise) {
    try {
      boolean streamStatus = RTMPManager.publisher.isStreaming();
      promise.resolve(streamStatus);
    } catch (Exception e) {
      promise.reject(e);
    }
  }

  @ReactMethod
  public void isCameraOnPreview(Promise promise) {
    try {
      boolean streamStatus = RTMPManager.publisher.isOnPreview();
      promise.resolve(streamStatus);
    } catch (Exception e) {
      promise.reject(e);
    }
  }

  @ReactMethod
  public void getPublishURL(Promise promise) {
    try {
      String url = RTMPManager.publisher.getPublishURL();
      promise.resolve(url);
    } catch (Exception e) {
      promise.reject(e);
    }
  }

  @ReactMethod
  public void hasCongestion(Promise promise) {
    try {
      boolean congestionStatus = RTMPManager.publisher.hasCongestion();
      promise.resolve(congestionStatus);
    } catch (Exception e) {
      promise.reject(e);
    }
  }

  @ReactMethod
  public void isAudioPrepared(Promise promise) {
    try {
      boolean status = RTMPManager.publisher.isAudioPrepared();
      promise.resolve(status);
    } catch (Exception e) {
      promise.reject(e);
    }
  }

  @ReactMethod
  public void isVideoPrepared(Promise promise) {
    try {
      boolean status = RTMPManager.publisher.isVideoPrepared();
      promise.resolve(status);
    } catch (Exception e) {
      promise.reject(e);
    }
  }

  @ReactMethod
  public void isMuted(Promise promise) {
    try {
      boolean status = RTMPManager.publisher.isAudioMuted();
      promise.resolve(status);
    } catch (Exception e) {
      promise.reject(e);
    }
  }

  @ReactMethod
  public void mute(Promise promise) {
    try {
      if (RTMPManager.publisher.isAudioMuted()) {
        return;
      }

      RTMPManager.publisher.disableAudio();
    } catch (Exception e) {
      promise.reject(e);
    }
  }

  @ReactMethod
  public void unmute(Promise promise) {
    try {
      if (!RTMPManager.publisher.isAudioMuted()) {
        return;
      }

      RTMPManager.publisher.enableAudio();
    } catch (Exception e) {
      promise.reject(e);
    }
  }

  @ReactMethod
  public void switchCamera(Promise promise) {
    try {
      RTMPManager.publisher.switchCamera();
    } catch (Exception e) {
      promise.reject(e);
    }
  }

  @ReactMethod
  public void startStream(Promise promise) {
    try {
      RTMPManager.publisher.startStream();
    } catch (Exception e) {
      promise.reject(e);
    }
  }

  @ReactMethod
  public void stopStream(Promise promise) {
    try {
      RTMPManager.publisher.stopStream();
    } catch (Exception e) {
      promise.reject(e);
    }
  }

  @ReactMethod
  public void toggleFlash(Promise promise) {
    try {
      RTMPManager.publisher.toggleFlash();
    } catch (Exception e) {
      promise.reject(e);
    }
  }

  @ReactMethod
  public void setAudioInput(int audioInputType, Promise promise) {
    try {
      AudioInputType selectedType = AudioInputType.values()[audioInputType];
      RTMPManager.publisher.setAudioInput(selectedType);
    } catch (Exception e) {
      promise.reject(e);
    }
  }
}


================================================
FILE: android/src/main/java/com/reactnativertmppublisher/RTMPPackage.java
================================================
package com.reactnativertmppublisher;

import androidx.annotation.NonNull;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class RTMPPackage implements ReactPackage {
  @NonNull
  @Override
  public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
    List<NativeModule> modules = new ArrayList<>();
    modules.add(new RTMPModule(reactContext));
    return modules;
  }

  @NonNull
  @Override
  public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
    return Collections.singletonList(
      new RTMPManager()
    );
  }
}




================================================
FILE: android/src/main/java/com/reactnativertmppublisher/enums/AudioInputType.java
================================================
package com.reactnativertmppublisher.enums;

public enum AudioInputType {
  BLUETOOTH_HEADSET,
  SPEAKER
}


================================================
FILE: android/src/main/java/com/reactnativertmppublisher/enums/BluetoothDeviceStatuses.java
================================================
package com.reactnativertmppublisher.enums;

public enum BluetoothDeviceStatuses {
  CONNECTING,
  CONNECTED,
  DISCONNECTED
}


================================================
FILE: android/src/main/java/com/reactnativertmppublisher/enums/StreamState.java
================================================
package com.reactnativertmppublisher.enums;

public enum StreamState {
  CONNECTING,
  CONNECTED,
  DISCONNECTED,
  FAILED
}


================================================
FILE: android/src/main/java/com/reactnativertmppublisher/interfaces/ConnectionListener.java
================================================
package com.reactnativertmppublisher.interfaces;

import androidx.annotation.Nullable;

public interface ConnectionListener {
    void onChange(String type, @Nullable Object data);
}


================================================
FILE: android/src/main/java/com/reactnativertmppublisher/modules/BluetoothDeviceConnector.java
================================================
package com.reactnativertmppublisher.modules;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothProfile;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;

import com.reactnativertmppublisher.enums.BluetoothDeviceStatuses;
import com.reactnativertmppublisher.interfaces.ConnectionListener;

import java.util.ArrayList;
import java.util.List;

public class BluetoothDeviceConnector extends BroadcastReceiver implements BluetoothProfile.ServiceListener{
  private final List<ConnectionListener> listeners = new ArrayList<>();

  public void addListener(ConnectionListener listener) {
    listeners.add(listener);
  }

  public BluetoothDeviceConnector(Context context) {
    BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    mBluetoothAdapter.getProfileProxy(context, this, BluetoothProfile.HEADSET);
    context.registerReceiver(this, new IntentFilter(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED));
  }

  @Override
  public void onServiceConnected(int i, BluetoothProfile bluetoothProfile) {
    if(bluetoothProfile.getConnectedDevices().size() > 0) {
        for (ConnectionListener l : listeners) {
        l.onChange("onBluetoothDeviceStatusChanged", BluetoothDeviceStatuses.CONNECTED.toString());
      }
    }
  }

  @Override
  public void onServiceDisconnected(int i) {
    for (ConnectionListener l : listeners) {
      l.onChange("onBluetoothDeviceStatusChanged", BluetoothDeviceStatuses.DISCONNECTED.toString());
    }
  }

  @Override
  public void onReceive(Context context, Intent intent) {
    int status = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, -1);

    switch (status){
      case BluetoothAdapter.STATE_CONNECTING: {
        for (ConnectionListener l : listeners) {
          l.onChange("onBluetoothDeviceStatusChanged", BluetoothDeviceStatuses.CONNECTING.toString());
        };
        break;
      }

      case BluetoothAdapter.STATE_CONNECTED: {
        for (ConnectionListener l : listeners) {
          l.onChange("onBluetoothDeviceStatusChanged", BluetoothDeviceStatuses.CONNECTED.toString());
        };
        break;
      }

      case BluetoothAdapter.STATE_DISCONNECTED: {
        for (ConnectionListener l : listeners) {
          l.onChange("onBluetoothDeviceStatusChanged", BluetoothDeviceStatuses.DISCONNECTED.toString());
        };
        break;
      }
    };

  }
}


================================================
FILE: android/src/main/java/com/reactnativertmppublisher/modules/ConnectionChecker.java
================================================
package com.reactnativertmppublisher.modules;

import androidx.annotation.NonNull;

import com.pedro.rtmp.utils.ConnectCheckerRtmp;
import com.reactnativertmppublisher.interfaces.ConnectionListener;

import java.util.ArrayList;
import java.util.List;

public class ConnectionChecker implements ConnectCheckerRtmp {
  private final List<ConnectionListener> listeners = new ArrayList<>();

  public void addListener(ConnectionListener listener) {
    listeners.add(listener);
  }

  @Override
  public void onAuthErrorRtmp() {
    for (ConnectionListener l : listeners) {
      l.onChange("onAuthError", null);
    }
  }

  @Override
  public void onAuthSuccessRtmp() {
    for (ConnectionListener l : listeners) {
      l.onChange("onAuthSuccess", null);
    }
  }

  // TODO: Parameters will be send after onChange method updated
  @Override
  public void onConnectionFailedRtmp(@NonNull String s) {
    for (ConnectionListener l : listeners) {
      l.onChange("onConnectionFailed", s);
    }
  }

  // TODO: Parameters will be send after onChange method updated
  @Override
  public void onConnectionStartedRtmp(@NonNull String s) {
    for (ConnectionListener l : listeners) {
      l.onChange("onConnectionStarted", s);
    }
  }

  @Override
  public void onConnectionSuccessRtmp() {
    for (ConnectionListener l : listeners) {
      l.onChange("onConnectionSuccess", null);
    }
  }

  @Override
  public void onDisconnectRtmp() {
    for (ConnectionListener l : listeners) {
      l.onChange("onDisconnect", null);
    }
  }

  // TODO: Parameters will be send after onChange method updated
  @Override
  public void onNewBitrateRtmp(long b) {
    for (ConnectionListener l : listeners) {
      l.onChange("onNewBitrateReceived", b);
    }
  }
}


================================================
FILE: android/src/main/java/com/reactnativertmppublisher/modules/Publisher.java
================================================
package com.reactnativertmppublisher.modules;

import android.content.Context;
import android.media.AudioManager;
import android.media.MediaRecorder;
import android.util.Log;
import android.view.SurfaceView;

import androidx.annotation.NonNull;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.events.RCTEventEmitter;
import com.pedro.rtplibrary.rtmp.RtmpCamera1;
import com.reactnativertmppublisher.enums.AudioInputType;
import com.reactnativertmppublisher.enums.StreamState;
import com.reactnativertmppublisher.interfaces.ConnectionListener;
import com.reactnativertmppublisher.utils.ObjectCaster;

public class Publisher {
  private final SurfaceView _surfaceView;
  private final RtmpCamera1 _rtmpCamera;
  private final ThemedReactContext _reactContext;
  private final AudioManager _mAudioManager;
  private String _streamUrl;
  private String _streamName;
  ConnectionChecker _connectionChecker = new ConnectionChecker();
  BluetoothDeviceConnector _bluetoothDeviceConnector;

  public Publisher(ThemedReactContext reactContext, SurfaceView surfaceView) {
    _reactContext = reactContext;
    _surfaceView = surfaceView;
    _rtmpCamera = new RtmpCamera1(surfaceView, _connectionChecker);
    _bluetoothDeviceConnector = new BluetoothDeviceConnector(reactContext);

    _bluetoothDeviceConnector.addListener(createBluetoothDeviceListener());
    _connectionChecker.addListener(createConnectionListener());
    _mAudioManager = (AudioManager) reactContext.getSystemService(Context.AUDIO_SERVICE);

    setAudioInput(AudioInputType.SPEAKER);
  }

  public RtmpCamera1 getRtmpCamera() {
    return _rtmpCamera;
  }

  public ConnectionListener createConnectionListener() {
    return (type, data) -> {
      eventEffect(type);
      WritableMap eventData = ObjectCaster.caster(data);

        _reactContext
          .getJSModule(RCTEventEmitter.class)
          .receiveEvent(_surfaceView.getId(), type, eventData);
    };
  }

  public ConnectionListener createBluetoothDeviceListener(){
    return (type, data) -> {
      eventEffect(type);
      WritableMap eventData = ObjectCaster.caster(data);

      _reactContext
        .getJSModule(RCTEventEmitter.class)
        .receiveEvent(_surfaceView.getId(), type, eventData);
    };
  }

  private void eventEffect(@NonNull String eventType) {
    switch (eventType) {
      case "onConnectionStarted": {
        WritableMap event = Arguments.createMap();
        event.putString("data", String.valueOf(StreamState.CONNECTING));

        _reactContext
          .getJSModule(RCTEventEmitter.class)
          .receiveEvent(_surfaceView.getId(), "onStreamStateChanged", event);
        break;
      }

      case "onConnectionSuccess": {
        WritableMap event = Arguments.createMap();
        event.putString("data", String.valueOf(StreamState.CONNECTED));

        _reactContext
          .getJSModule(RCTEventEmitter.class)
          .receiveEvent(_surfaceView.getId(), "onStreamStateChanged", event);
        break;
      }

      case "onDisconnect": {
        WritableMap event = Arguments.createMap();
        event.putString("data", String.valueOf(StreamState.DISCONNECTED));

        _reactContext
          .getJSModule(RCTEventEmitter.class)
          .receiveEvent(_surfaceView.getId(), "onStreamStateChanged", event);
        break;
      }

      case "onConnectionFailed": {
        WritableMap event = Arguments.createMap();
        event.putString("data", String.valueOf(StreamState.FAILED));

        _reactContext
          .getJSModule(RCTEventEmitter.class)
          .receiveEvent(_surfaceView.getId(), "onStreamStateChanged", event);
        break;
      }
    }
  }


  //region COMPONENT METHODS
  public String getPublishURL() {
    return _streamUrl + "/" + _streamName;
  }

  public void setStreamUrl(String _streamUrl) {
    this._streamUrl = _streamUrl;
  }

  public void setStreamName(String _streamName) {
    this._streamName = _streamName;
  }

  public boolean isStreaming() {
    return _rtmpCamera.isStreaming();
  }

  public boolean isOnPreview() {
    return _rtmpCamera.isOnPreview();
  }

  public boolean isAudioPrepared() {
    return _rtmpCamera.prepareAudio();
  }

  public boolean isVideoPrepared() {
    return _rtmpCamera.prepareVideo();
  }

  public boolean hasCongestion() {
    return _rtmpCamera.hasCongestion();
  }

  public boolean isAudioMuted() {
    return _rtmpCamera.isAudioMuted();
  }

  public void disableAudio() {
    _rtmpCamera.disableAudio();
  }

  public void enableAudio() {
    _rtmpCamera.enableAudio();
  }

  public void switchCamera() {
    _rtmpCamera.switchCamera();
  }

  public void toggleFlash() {
    try {
      if(_rtmpCamera.isLanternEnabled()){
        _rtmpCamera.disableLantern();
        return;
      }

      _rtmpCamera.enableLantern();
    }
    catch (Exception e){
      e.printStackTrace();
    }
  }

  public void startStream() {
    try {
      boolean isAudioPrepared = _rtmpCamera.prepareAudio(MediaRecorder.AudioSource.DEFAULT, 128 * 1024, 44100, true, false, false);
      boolean isVideoPrepared = _rtmpCamera.prepareVideo(1280 , 720, 3000 * 1024);

      if (!isAudioPrepared || !isVideoPrepared || _streamName == null || _streamUrl == null) {
        return;
      }

      String url = _streamUrl + "/" + _streamName;
      _rtmpCamera.startStream(url);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public void stopStream() {
    try {
      boolean isStreaming = _rtmpCamera.isStreaming();

      if (!isStreaming) {
        return;
      }

      _rtmpCamera.stopStream();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public void setAudioInput(@NonNull AudioInputType audioInputType){
    System.out.println(audioInputType);
    switch (audioInputType){
      case BLUETOOTH_HEADSET: {
        System.out.println("ble");
        try{
          _mAudioManager.startBluetoothSco();
          _mAudioManager.setBluetoothScoOn(true);
          break;
        }
        catch (Exception error){
          System.out.println(error);
          break;
        }
      }

      case SPEAKER:{
        try{
          if(_mAudioManager.isBluetoothScoOn()){
            _mAudioManager.stopBluetoothSco();
            _mAudioManager.setBluetoothScoOn(false);
          }

          _mAudioManager.setSpeakerphoneOn(true);
          break;
        }
        catch (Exception error){
          System.out.println(error);
          break;
        }
      }
    }
  }
  //endregion

}


================================================
FILE: android/src/main/java/com/reactnativertmppublisher/modules/SurfaceHolderHelper.java
================================================
package com.reactnativertmppublisher.modules;


import android.view.SurfaceHolder;

import androidx.annotation.NonNull;

import com.facebook.react.uimanager.ThemedReactContext;
import com.pedro.rtplibrary.rtmp.RtmpCamera1;

public class SurfaceHolderHelper implements SurfaceHolder.Callback {
  private final RtmpCamera1 _rtmpCamera1;

  public SurfaceHolderHelper(ThemedReactContext reactContext, RtmpCamera1 rtmpCamera1, int surfaceId) {
    _rtmpCamera1 = rtmpCamera1;
  }

  @Override
  public void surfaceCreated(@NonNull SurfaceHolder surfaceHolder) {

  }

  @Override
  public void surfaceChanged(@NonNull SurfaceHolder surfaceHolder, int i, int i1, int i2) {
    _rtmpCamera1.startPreview(1280 , 720);
  }

  @Override
  public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {
    _rtmpCamera1.stopPreview();
  }

}


================================================
FILE: android/src/main/java/com/reactnativertmppublisher/utils/ObjectCaster.java
================================================
package com.reactnativertmppublisher.utils;

import androidx.annotation.Nullable;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.WritableMap;

public class ObjectCaster {
  public static WritableMap caster(@Nullable Object data){
    WritableMap event = Arguments.createMap();

    if(data == null){
      event.putNull("data");
    }

    if(data instanceof String){
      event.putString("data", (String) data);
    }

    if(data instanceof Integer){
      event.putInt("data", (Integer) data);
    }

    if(data instanceof Boolean){
      event.putBoolean("data", (Boolean) data);
    }

    if(data instanceof Long){
      event.putDouble("data", (Long) data);
    }

    return event;
  }
}


================================================
FILE: babel.config.js
================================================
module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
};


================================================
FILE: coverage/clover.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<coverage generated="1674417315429" clover="3.2.0">
  <project timestamp="1674417315429" name="All files">
    <metrics statements="0" coveredstatements="0" conditionals="0" coveredconditionals="0" methods="0" coveredmethods="0" elements="0" coveredelements="0" complexity="0" loc="0" ncloc="0" packages="0" files="0" classes="0"/>
  </project>
</coverage>


================================================
FILE: coverage/coverage-final.json
================================================
{}


================================================
FILE: coverage/lcov-report/Component.tsx.html
================================================

<!doctype html>
<html lang="en">

<head>
    <title>Code coverage report for Component.tsx</title>
    <meta charset="utf-8" />
    <link rel="stylesheet" href="prettify.css" />
    <link rel="stylesheet" href="base.css" />
    <link rel="shortcut icon" type="image/x-icon" href="favicon.png" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style type='text/css'>
        .coverage-summary .sorter {
            background-image: url(sort-arrow-sprite.png);
        }
    </style>
</head>
    
<body>
<div class='wrapper'>
    <div class='pad1'>
        <h1><a href="index.html">All files</a> Component.tsx</h1>
        <div class='clearfix'>
            
            <div class='fl pad1y space-right2'>
                <span class="strong">0% </span>
                <span class="quiet">Statements</span>
                <span class='fraction'>0/0</span>
            </div>
        
            
            <div class='fl pad1y space-right2'>
                <span class="strong">0% </span>
                <span class="quiet">Branches</span>
                <span class='fraction'>0/0</span>
            </div>
        
            
            <div class='fl pad1y space-right2'>
                <span class="strong">0% </span>
                <span class="quiet">Functions</span>
                <span class='fraction'>0/0</span>
            </div>
        
            
            <div class='fl pad1y space-right2'>
                <span class="strong">0% </span>
                <span class="quiet">Lines</span>
                <span class='fraction'>0/0</span>
            </div>
        
            
        </div>
        <p class="quiet">
            Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
        </p>
        <template id="filterTemplate">
            <div class="quiet">
                Filter:
                <input oninput="onInput()" type="search" id="fileSearch">
            </div>
        </template>
    </div>
    <div class='status-line low'></div>
    <pre><table class="coverage">
<tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
<a name='L2'></a><a href='#L2'>2</a>
<a name='L3'></a><a href='#L3'>3</a>
<a name='L4'></a><a href='#L4'>4</a>
<a name='L5'></a><a href='#L5'>5</a>
<a name='L6'></a><a href='#L6'>6</a>
<a name='L7'></a><a href='#L7'>7</a>
<a name='L8'></a><a href='#L8'>8</a>
<a name='L9'></a><a href='#L9'>9</a>
<a name='L10'></a><a href='#L10'>10</a>
<a name='L11'></a><a href='#L11'>11</a>
<a name='L12'></a><a href='#L12'>12</a>
<a name='L13'></a><a href='#L13'>13</a>
<a name='L14'></a><a href='#L14'>14</a>
<a name='L15'></a><a href='#L15'>15</a>
<a name='L16'></a><a href='#L16'>16</a>
<a name='L17'></a><a href='#L17'>17</a>
<a name='L18'></a><a href='#L18'>18</a>
<a name='L19'></a><a href='#L19'>19</a>
<a name='L20'></a><a href='#L20'>20</a>
<a name='L21'></a><a href='#L21'>21</a>
<a name='L22'></a><a href='#L22'>22</a>
<a name='L23'></a><a href='#L23'>23</a>
<a name='L24'></a><a href='#L24'>24</a>
<a name='L25'></a><a href='#L25'>25</a>
<a name='L26'></a><a href='#L26'>26</a>
<a name='L27'></a><a href='#L27'>27</a>
<a name='L28'></a><a href='#L28'>28</a>
<a name='L29'></a><a href='#L29'>29</a>
<a name='L30'></a><a href='#L30'>30</a>
<a name='L31'></a><a href='#L31'>31</a>
<a name='L32'></a><a href='#L32'>32</a>
<a name='L33'></a><a href='#L33'>33</a>
<a name='L34'></a><a href='#L34'>34</a>
<a name='L35'></a><a href='#L35'>35</a>
<a name='L36'></a><a href='#L36'>36</a>
<a name='L37'></a><a href='#L37'>37</a>
<a name='L38'></a><a href='#L38'>38</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">import {
  NativeSyntheticEvent,
  requireNativeComponent,
  ViewStyle,
} from 'react-native';
import type { StreamState, BluetoothDeviceStatuses } from './types';
&nbsp;
type RTMPData&lt;T&gt; = { data: T };
&nbsp;
export type ConnectionFailedType = NativeSyntheticEvent&lt;RTMPData&lt;string&gt;&gt;;
export type ConnectionStartedType = NativeSyntheticEvent&lt;RTMPData&lt;string&gt;&gt;;
export type ConnectionSuccessType = NativeSyntheticEvent&lt;RTMPData&lt;null&gt;&gt;;
export type DisconnectType = NativeSyntheticEvent&lt;RTMPData&lt;null&gt;&gt;;
export type NewBitrateReceivedType = NativeSyntheticEvent&lt;RTMPData&lt;number&gt;&gt;;
export type StreamStateChangedType = NativeSyntheticEvent&lt;
  RTMPData&lt;StreamState&gt;
&gt;;
export type BluetoothDeviceStatusChangedType = NativeSyntheticEvent&lt;
  RTMPData&lt;BluetoothDeviceStatuses&gt;
&gt;;
export interface NativeRTMPPublisherProps {
  style?: ViewStyle;
  streamURL: string;
  streamName: string;
  onConnectionFailed?: (e: ConnectionFailedType) =&gt; void;
  onConnectionStarted?: (e: ConnectionStartedType) =&gt; void;
  onConnectionSuccess?: (e: ConnectionSuccessType) =&gt; void;
  onDisconnect?: (e: DisconnectType) =&gt; void;
  onNewBitrateReceived?: (e: NewBitrateReceivedType) =&gt; void;
  onStreamStateChanged?: (e: StreamStateChangedType) =&gt; void;
  onBluetoothDeviceStatusChanged?: (
    e: BluetoothDeviceStatusChangedType
  ) =&gt; void;
}
export default requireNativeComponent&lt;NativeRTMPPublisherProps&gt;(
  'RTMPPublisher'
);
&nbsp;</pre></td></tr></table></pre>

                <div class='push'></div><!-- for sticky footer -->
            </div><!-- /wrapper -->
            <div class='footer quiet pad2 space-top1 center small'>
                Code coverage generated by
                <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
                at Sun Jan 22 2023 22:43:48 GMT+0300 (GMT+03:00)
            </div>
        <script src="prettify.js"></script>
        <script>
            window.onload = function () {
                prettyPrint();
            };
        </script>
        <script src="sorter.js"></script>
        <script src="block-navigation.js"></script>
    </body>
</html>
    

================================================
FILE: coverage/lcov-report/RTMPPublisher.tsx.html
================================================

<!doctype html>
<html lang="en">

<head>
    <title>Code coverage report for RTMPPublisher.tsx</title>
    <meta charset="utf-8" />
    <link rel="stylesheet" href="prettify.css" />
    <link rel="stylesheet" href="base.css" />
    <link rel="shortcut icon" type="image/x-icon" href="favicon.png" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style type='text/css'>
        .coverage-summary .sorter {
            background-image: url(sort-arrow-sprite.png);
        }
    </style>
</head>
    
<body>
<div class='wrapper'>
    <div class='pad1'>
        <h1><a href="index.html">All files</a> RTMPPublisher.tsx</h1>
        <div class='clearfix'>
            
            <div class='fl pad1y space-right2'>
                <span class="strong">68.08% </span>
                <span class="quiet">Statements</span>
                <span class='fraction'>32/47</span>
            </div>
        
            
            <div class='fl pad1y space-right2'>
                <span class="strong">100% </span>
                <span class="quiet">Branches</span>
                <span class='fraction'>14/14</span>
            </div>
        
            
            <div class='fl pad1y space-right2'>
                <span class="strong">34.78% </span>
                <span class="quiet">Functions</span>
                <span class='fraction'>8/23</span>
            </div>
        
            
            <div class='fl pad1y space-right2'>
                <span class="strong">96.96% </span>
                <span class="quiet">Lines</span>
                <span class='fraction'>32/33</span>
            </div>
        
            
        </div>
        <p class="quiet">
            Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
        </p>
        <template id="filterTemplate">
            <div class="quiet">
                Filter:
                <input oninput="onInput()" type="search" id="fileSearch">
            </div>
        </template>
    </div>
    <div class='status-line medium'></div>
    <pre><table class="coverage">
<tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
<a name='L2'></a><a href='#L2'>2</a>
<a name='L3'></a><a href='#L3'>3</a>
<a name='L4'></a><a href='#L4'>4</a>
<a name='L5'></a><a href='#L5'>5</a>
<a name='L6'></a><a href='#L6'>6</a>
<a name='L7'></a><a href='#L7'>7</a>
<a name='L8'></a><a href='#L8'>8</a>
<a name='L9'></a><a href='#L9'>9</a>
<a name='L10'></a><a href='#L10'>10</a>
<a name='L11'></a><a href='#L11'>11</a>
<a name='L12'></a><a href='#L12'>12</a>
<a name='L13'></a><a href='#L13'>13</a>
<a name='L14'></a><a href='#L14'>14</a>
<a name='L15'></a><a href='#L15'>15</a>
<a name='L16'></a><a href='#L16'>16</a>
<a name='L17'></a><a href='#L17'>17</a>
<a name='L18'></a><a href='#L18'>18</a>
<a name='L19'></a><a href='#L19'>19</a>
<a name='L20'></a><a href='#L20'>20</a>
<a name='L21'></a><a href='#L21'>21</a>
<a name='L22'></a><a href='#L22'>22</a>
<a name='L23'></a><a href='#L23'>23</a>
<a name='L24'></a><a href='#L24'>24</a>
<a name='L25'></a><a href='#L25'>25</a>
<a name='L26'></a><a href='#L26'>26</a>
<a name='L27'></a><a href='#L27'>27</a>
<a name='L28'></a><a href='#L28'>28</a>
<a name='L29'></a><a href='#L29'>29</a>
<a name='L30'></a><a href='#L30'>30</a>
<a name='L31'></a><a href='#L31'>31</a>
<a name='L32'></a><a href='#L32'>32</a>
<a name='L33'></a><a href='#L33'>33</a>
<a name='L34'></a><a href='#L34'>34</a>
<a name='L35'></a><a href='#L35'>35</a>
<a name='L36'></a><a href='#L36'>36</a>
<a name='L37'></a><a href='#L37'>37</a>
<a name='L38'></a><a href='#L38'>38</a>
<a name='L39'></a><a href='#L39'>39</a>
<a name='L40'></a><a href='#L40'>40</a>
<a name='L41'></a><a href='#L41'>41</a>
<a name='L42'></a><a href='#L42'>42</a>
<a name='L43'></a><a href='#L43'>43</a>
<a name='L44'></a><a href='#L44'>44</a>
<a name='L45'></a><a href='#L45'>45</a>
<a name='L46'></a><a href='#L46'>46</a>
<a name='L47'></a><a href='#L47'>47</a>
<a name='L48'></a><a href='#L48'>48</a>
<a name='L49'></a><a href='#L49'>49</a>
<a name='L50'></a><a href='#L50'>50</a>
<a name='L51'></a><a href='#L51'>51</a>
<a name='L52'></a><a href='#L52'>52</a>
<a name='L53'></a><a href='#L53'>53</a>
<a name='L54'></a><a href='#L54'>54</a>
<a name='L55'></a><a href='#L55'>55</a>
<a name='L56'></a><a href='#L56'>56</a>
<a name='L57'></a><a href='#L57'>57</a>
<a name='L58'></a><a href='#L58'>58</a>
<a name='L59'></a><a href='#L59'>59</a>
<a name='L60'></a><a href='#L60'>60</a>
<a name='L61'></a><a href='#L61'>61</a>
<a name='L62'></a><a href='#L62'>62</a>
<a name='L63'></a><a href='#L63'>63</a>
<a name='L64'></a><a href='#L64'>64</a>
<a name='L65'></a><a href='#L65'>65</a>
<a name='L66'></a><a href='#L66'>66</a>
<a name='L67'></a><a href='#L67'>67</a>
<a name='L68'></a><a href='#L68'>68</a>
<a name='L69'></a><a href='#L69'>69</a>
<a name='L70'></a><a href='#L70'>70</a>
<a name='L71'></a><a href='#L71'>71</a>
<a name='L72'></a><a href='#L72'>72</a>
<a name='L73'></a><a href='#L73'>73</a>
<a name='L74'></a><a href='#L74'>74</a>
<a name='L75'></a><a href='#L75'>75</a>
<a name='L76'></a><a href='#L76'>76</a>
<a name='L77'></a><a href='#L77'>77</a>
<a name='L78'></a><a href='#L78'>78</a>
<a name='L79'></a><a href='#L79'>79</a>
<a name='L80'></a><a href='#L80'>80</a>
<a name='L81'></a><a href='#L81'>81</a>
<a name='L82'></a><a href='#L82'>82</a>
<a name='L83'></a><a href='#L83'>83</a>
<a name='L84'></a><a href='#L84'>84</a>
<a name='L85'></a><a href='#L85'>85</a>
<a name='L86'></a><a href='#L86'>86</a>
<a name='L87'></a><a href='#L87'>87</a>
<a name='L88'></a><a href='#L88'>88</a>
<a name='L89'></a><a href='#L89'>89</a>
<a name='L90'></a><a href='#L90'>90</a>
<a name='L91'></a><a href='#L91'>91</a>
<a name='L92'></a><a href='#L92'>92</a>
<a name='L93'></a><a href='#L93'>93</a>
<a name='L94'></a><a href='#L94'>94</a>
<a name='L95'></a><a href='#L95'>95</a>
<a name='L96'></a><a href='#L96'>96</a>
<a name='L97'></a><a href='#L97'>97</a>
<a name='L98'></a><a href='#L98'>98</a>
<a name='L99'></a><a href='#L99'>99</a>
<a name='L100'></a><a href='#L100'>100</a>
<a name='L101'></a><a href='#L101'>101</a>
<a name='L102'></a><a href='#L102'>102</a>
<a name='L103'></a><a href='#L103'>103</a>
<a name='L104'></a><a href='#L104'>104</a>
<a name='L105'></a><a href='#L105'>105</a>
<a name='L106'></a><a href='#L106'>106</a>
<a name='L107'></a><a href='#L107'>107</a>
<a name='L108'></a><a href='#L108'>108</a>
<a name='L109'></a><a href='#L109'>109</a>
<a name='L110'></a><a href='#L110'>110</a>
<a name='L111'></a><a href='#L111'>111</a>
<a name='L112'></a><a href='#L112'>112</a>
<a name='L113'></a><a href='#L113'>113</a>
<a name='L114'></a><a href='#L114'>114</a>
<a name='L115'></a><a href='#L115'>115</a>
<a name='L116'></a><a href='#L116'>116</a>
<a name='L117'></a><a href='#L117'>117</a>
<a name='L118'></a><a href='#L118'>118</a>
<a name='L119'></a><a href='#L119'>119</a>
<a name='L120'></a><a href='#L120'>120</a>
<a name='L121'></a><a href='#L121'>121</a>
<a name='L122'></a><a href='#L122'>122</a>
<a name='L123'></a><a href='#L123'>123</a>
<a name='L124'></a><a href='#L124'>124</a>
<a name='L125'></a><a href='#L125'>125</a>
<a name='L126'></a><a href='#L126'>126</a>
<a name='L127'></a><a href='#L127'>127</a>
<a name='L128'></a><a href='#L128'>128</a>
<a name='L129'></a><a href='#L129'>129</a>
<a name='L130'></a><a href='#L130'>130</a>
<a name='L131'></a><a href='#L131'>131</a>
<a name='L132'></a><a href='#L132'>132</a>
<a name='L133'></a><a href='#L133'>133</a>
<a name='L134'></a><a href='#L134'>134</a>
<a name='L135'></a><a href='#L135'>135</a>
<a name='L136'></a><a href='#L136'>136</a>
<a name='L137'></a><a href='#L137'>137</a>
<a name='L138'></a><a href='#L138'>138</a>
<a name='L139'></a><a href='#L139'>139</a>
<a name='L140'></a><a href='#L140'>140</a>
<a name='L141'></a><a href='#L141'>141</a>
<a name='L142'></a><a href='#L142'>142</a>
<a name='L143'></a><a href='#L143'>143</a>
<a name='L144'></a><a href='#L144'>144</a>
<a name='L145'></a><a href='#L145'>145</a>
<a name='L146'></a><a href='#L146'>146</a>
<a name='L147'></a><a href='#L147'>147</a>
<a name='L148'></a><a href='#L148'>148</a>
<a name='L149'></a><a href='#L149'>149</a>
<a name='L150'></a><a href='#L150'>150</a>
<a name='L151'></a><a href='#L151'>151</a>
<a name='L152'></a><a href='#L152'>152</a>
<a name='L153'></a><a href='#L153'>153</a>
<a name='L154'></a><a href='#L154'>154</a>
<a name='L155'></a><a href='#L155'>155</a>
<a name='L156'></a><a href='#L156'>156</a>
<a name='L157'></a><a href='#L157'>157</a>
<a name='L158'></a><a href='#L158'>158</a>
<a name='L159'></a><a href='#L159'>159</a>
<a name='L160'></a><a href='#L160'>160</a>
<a name='L161'></a><a href='#L161'>161</a>
<a name='L162'></a><a href='#L162'>162</a>
<a name='L163'></a><a href='#L163'>163</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">8x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">8x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">8x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">8x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">8x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">8x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">8x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">8x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">8x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">8x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">8x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">8x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">8x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">8x</span>
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">8x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">8x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">8x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">8x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">8x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">8x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">8x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">8x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">8x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">import React, { forwardRef, useImperativeHandle } from 'react';
import { NativeModules, type ViewStyle } from 'react-native';
import PublisherComponent, {
  type DisconnectType,
  type ConnectionFailedType,
  type ConnectionStartedType,
  type ConnectionSuccessType,
  type NewBitrateReceivedType,
  type StreamStateChangedType,
  type BluetoothDeviceStatusChangedType,
} from './Component';
import type {
  RTMPPublisherRefProps,
  StreamState,
  BluetoothDeviceStatuses,
  AudioInputType,
} from './types';
&nbsp;
const RTMPModule = NativeModules.RTMPPublisher;
export interface RTMPPublisherProps {
  testID?: string;
  style?: ViewStyle;
  streamURL: string;
  streamName: string;
  /**
   * Callback for connection fails on RTMP server
   */
  onConnectionFailed?: (data: string) =&gt; void;
  /**
   * Callback for starting connection to RTMP server
   */
  onConnectionStarted?: (data: string) =&gt; void;
  /**
   * Callback for connection successfully to RTMP server
   */
  onConnectionSuccess?: (data: null) =&gt; void;
  /**
   * Callback for disconnect successfully to RTMP server
   */
  onDisconnect?: (data: null) =&gt; void;
  /**
   * Callback for receiving new bitrate value about stream
   */
  onNewBitrateReceived?: (data: number) =&gt; void;
  /**
   * Alternatively callback for changing stream state
   * Returns parameter StreamState type
   */
  onStreamStateChanged?: (data: StreamState) =&gt; void;
  /**
   * Callback for bluetooth device connection changes
   */
  onBluetoothDeviceStatusChanged?: (data: BluetoothDeviceStatuses) =&gt; void;
}
&nbsp;
const RTMPPublisher = forwardRef&lt;RTMPPublisherRefProps, RTMPPublisherProps&gt;(
  (
    {
      onConnectionFailed,
      onConnectionStarted,
      onConnectionSuccess,
      onDisconnect,
      onNewBitrateReceived,
      onStreamStateChanged,
      onBluetoothDeviceStatusChanged,
      ...props
    },
    ref
  ) =&gt; {
    const startStream = <span class="fstat-no" title="function not covered" >as</span>ync () =&gt; <span class="cstat-no" title="statement not covered" >await RTMPModule.startStream();</span>
&nbsp;
    const stopStream = <span class="fstat-no" title="function not covered" >as</span>ync () =&gt; <span class="cstat-no" title="statement not covered" >await RTMPModule.stopStream();</span>
&nbsp;
    const isStreaming = <span class="fstat-no" title="function not covered" >as</span>ync () =&gt; <span class="cstat-no" title="statement not covered" >RTMPModule.isStreaming();</span>
&nbsp;
    const isCameraOnPreview = <span class="fstat-no" title="function not covered" >as</span>ync () =&gt; <span class="cstat-no" title="statement not covered" >RTMPModule.isCameraOnPreview();</span>
&nbsp;
    const getPublishURL = <span class="fstat-no" title="function not covered" >as</span>ync () =&gt; <span class="cstat-no" title="statement not covered" >RTMPModule.getPublishURL();</span>
&nbsp;
    const hasCongestion = <span class="fstat-no" title="function not covered" >as</span>ync () =&gt; <span class="cstat-no" title="statement not covered" >RTMPModule.hasCongestion();</span>
&nbsp;
    const isAudioPrepared = <span class="fstat-no" title="function not covered" >as</span>ync () =&gt; <span class="cstat-no" title="statement not covered" >RTMPModule.isAudioPrepared();</span>
&nbsp;
    const isVideoPrepared = <span class="fstat-no" title="function not covered" >as</span>ync () =&gt; <span class="cstat-no" title="statement not covered" >RTMPModule.isVideoPrepared();</span>
&nbsp;
    const isMuted = <span class="fstat-no" title="function not covered" >as</span>ync () =&gt; <span class="cstat-no" title="statement not covered" >RTMPModule.isMuted();</span>
&nbsp;
    const mute = <span class="fstat-no" title="function not covered" >()</span> =&gt; <span class="cstat-no" title="statement not covered" >RTMPModule.mute();</span>
&nbsp;
    const unmute = <span class="fstat-no" title="function not covered" >()</span> =&gt; <span class="cstat-no" title="statement not covered" >RTMPModule.unmute();</span>
&nbsp;
    const switchCamera = <span class="fstat-no" title="function not covered" >()</span> =&gt; <span class="cstat-no" title="statement not covered" >RTMPModule.switchCamera();</span>
&nbsp;
    const toggleFlash = <span class="fstat-no" title="function not covered" >()</span> =&gt; <span class="cstat-no" title="statement not covered" >RTMPModule.toggleFlash();</span>
&nbsp;
    const setAudioInput = <span class="fstat-no" title="function not covered" >(a</span>udioInput: AudioInputType) =&gt;
<span class="cstat-no" title="statement not covered" >      RTMPModule.setAudioInput(audioInput);</span>
&nbsp;
    const handleOnConnectionFailed = (e: ConnectionFailedType) =&gt; {
      onConnectionFailed &amp;&amp; onConnectionFailed(e.nativeEvent.data);
    };
&nbsp;
    const handleOnConnectionStarted = (e: ConnectionStartedType) =&gt; {
      onConnectionStarted &amp;&amp; onConnectionStarted(e.nativeEvent.data);
    };
&nbsp;
    const handleOnConnectionSuccess = (e: ConnectionSuccessType) =&gt; {
      onConnectionSuccess &amp;&amp; onConnectionSuccess(e.nativeEvent.data);
    };
&nbsp;
    const handleOnDisconnect = (e: DisconnectType) =&gt; {
      onDisconnect &amp;&amp; onDisconnect(e.nativeEvent.data);
    };
&nbsp;
    const handleOnNewBitrateReceived = (e: NewBitrateReceivedType) =&gt; {
      onNewBitrateReceived &amp;&amp; onNewBitrateReceived(e.nativeEvent.data);
    };
&nbsp;
    const handleOnStreamStateChanged = (e: StreamStateChangedType) =&gt; {
      onStreamStateChanged &amp;&amp; onStreamStateChanged(e.nativeEvent.data);
    };
&nbsp;
    const handleBluetoothDeviceStatusChanged = (
      e: BluetoothDeviceStatusChangedType
    ) =&gt; {
      onBluetoothDeviceStatusChanged &amp;&amp;
        onBluetoothDeviceStatusChanged(e.nativeEvent.data);
    };
&nbsp;
    useImperativeHandle(ref, <span class="fstat-no" title="function not covered" >()</span> =&gt; (<span class="cstat-no" title="statement not covered" >{</span>
      startStream,
      stopStream,
      isStreaming,
      isCameraOnPreview,
      getPublishURL,
      hasCongestion,
      isAudioPrepared,
      isVideoPrepared,
      isMuted,
      mute,
      unmute,
      switchCamera,
      toggleFlash,
      setAudioInput,
    }));
&nbsp;
    return (
      &lt;PublisherComponent
        {...props}
        onDisconnect={handleOnDisconnect}
        onConnectionFailed={handleOnConnectionFailed}
        onConnectionStarted={handleOnConnectionStarted}
        onConnectionSuccess={handleOnConnectionSuccess}
        onNewBitrateReceived={handleOnNewBitrateReceived}
        onStreamStateChanged={handleOnStreamStateChanged}
        onBluetoothDeviceStatusChanged={handleBluetoothDeviceStatusChanged}
      /&gt;
    );
  }
);
&nbsp;
export default RTMPPublisher;
&nbsp;</pre></td></tr></table></pre>

                <div class='push'></div><!-- for sticky footer -->
            </div><!-- /wrapper -->
            <div class='footer quiet pad2 space-top1 center small'>
                Code coverage generated by
                <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
                at Sun Jan 22 2023 22:43:48 GMT+0300 (GMT+03:00)
            </div>
        <script src="prettify.js"></script>
        <script>
            window.onload = function () {
                prettyPrint();
            };
        </script>
        <script src="sorter.js"></script>
        <script src="block-navigation.js"></script>
    </body>
</html>
    

================================================
FILE: coverage/lcov-report/base.css
================================================
body, html {
  margin:0; padding: 0;
  height: 100%;
}
body {
    font-family: Helvetica Neue, Helvetica, Arial;
    font-size: 14px;
    color:#333;
}
.small { font-size: 12px; }
*, *:after, *:before {
  -webkit-box-sizing:border-box;
     -moz-box-sizing:border-box;
          box-sizing:border-box;
  }
h1 { font-size: 20px; margin: 0;}
h2 { font-size: 14px; }
pre {
    font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace;
    margin: 0;
    padding: 0;
    -moz-tab-size: 2;
    -o-tab-size:  2;
    tab-size: 2;
}
a { color:#0074D9; text-decoration:none; }
a:hover { text-decoration:underline; }
.strong { font-weight: bold; }
.space-top1 { padding: 10px 0 0 0; }
.pad2y { padding: 20px 0; }
.pad1y { padding: 10px 0; }
.pad2x { padding: 0 20px; }
.pad2 { padding: 20px; }
.pad1 { padding: 10px; }
.space-left2 { padding-left:55px; }
.space-right2 { padding-right:20px; }
.center { text-align:center; }
.clearfix { display:block; }
.clearfix:after {
  content:'';
  display:block;
  height:0;
  clear:both;
  visibility:hidden;
  }
.fl { float: left; }
@media only screen and (max-width:640px) {
  .col3 { width:100%; max-width:100%; }
  .hide-mobile { display:none!important; }
}

.quiet {
  color: #7f7f7f;
  color: rgba(0,0,0,0.5);
}
.quiet a { opacity: 0.7; }

.fraction {
  font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace;
  font-size: 10px;
  color: #555;
  background: #E8E8E8;
  padding: 4px 5px;
  border-radius: 3px;
  vertical-align: middle;
}

div.path a:link, div.path a:visited { color: #333; }
table.coverage {
  border-collapse: collapse;
  margin: 10px 0 0 0;
  padding: 0;
}

table.coverage td {
  margin: 0;
  padding: 0;
  vertical-align: top;
}
table.coverage td.line-count {
    text-align: right;
    padding: 0 5px 0 20px;
}
table.coverage td.line-coverage {
    text-align: right;
    padding-right: 10px;
    min-width:20px;
}

table.coverage td span.cline-any {
    display: inline-block;
    padding: 0 5px;
    width: 100%;
}
.missing-if-branch {
    display: inline-block;
    margin-right: 5px;
    border-radius: 3px;
    position: relative;
    padding: 0 4px;
    background: #333;
    color: yellow;
}

.skip-if-branch {
    display: none;
    margin-right: 10px;
    position: relative;
    padding: 0 4px;
    background: #ccc;
    color: white;
}
.missing-if-branch .typ, .skip-if-branch .typ {
    color: inherit !important;
}
.coverage-summary {
  border-collapse: collapse;
  width: 100%;
}
.coverage-summary tr { border-bottom: 1px solid #bbb; }
.keyline-all { border: 1px solid #ddd; }
.coverage-summary td, .coverage-summary th { padding: 10px; }
.coverage-summary tbody { border: 1px solid #bbb; }
.coverage-summary td { border-right: 1px solid #bbb; }
.coverage-summary td:last-child { border-right: none; }
.coverage-summary th {
  text-align: left;
  font-weight: normal;
  white-space: nowrap;
}
.coverage-summary th.file { border-right: none !important; }
.coverage-summary th.pct { }
.coverage-summary th.pic,
.coverage-summary th.abs,
.coverage-summary td.pct,
.coverage-summary td.abs { text-align: right; }
.coverage-summary td.file { white-space: nowrap;  }
.coverage-summary td.pic { min-width: 120px !important;  }
.coverage-summary tfoot td { }

.coverage-summary .sorter {
    height: 10px;
    width: 7px;
    display: inline-block;
    margin-left: 0.5em;
    background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent;
}
.coverage-summary .sorted .sorter {
    background-position: 0 -20px;
}
.coverage-summary .sorted-desc .sorter {
    background-position: 0 -10px;
}
.status-line {  height: 10px; }
/* yellow */
.cbranch-no { background: yellow !important; color: #111; }
/* dark red */
.red.solid, .status-line.low, .low .cover-fill { background:#C21F39 }
.low .chart { border:1px solid #C21F39 }
.highlighted,
.highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{
  background: #C21F39 !important;
}
/* medium red */
.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE }
/* light red */
.low, .cline-no { background:#FCE1E5 }
/* light green */
.high, .cline-yes { background:rgb(230,245,208) }
/* medium green */
.cstat-yes { background:rgb(161,215,106) }
/* dark green */
.status-line.high, .high .cover-fill { background:rgb(77,146,33) }
.high .chart { border:1px solid rgb(77,146,33) }
/* dark yellow (gold) */
.status-line.medium, .medium .cover-fill { background: #f9cd0b; }
.medium .chart { border:1px solid #f9cd0b; }
/* light yellow */
.medium { background: #fff4c2; }

.cstat-skip { background: #ddd; color: #111; }
.fstat-skip { background: #ddd; color: #111 !important; }
.cbranch-skip { background: #ddd !important; color: #111; }

span.cline-neutral { background: #eaeaea; }

.coverage-summary td.empty {
    opacity: .5;
    padding-top: 4px;
    padding-bottom: 4px;
    line-height: 1;
    color: #888;
}

.cover-fill, .cover-empty {
  display:inline-block;
  height: 12px;
}
.chart {
  line-height: 0;
}
.cover-empty {
    background: white;
}
.cover-full {
    border-right: none !important;
}
pre.prettyprint {
    border: none !important;
    padding: 0 !important;
    margin: 0 !important;
}
.com { color: #999 !important; }
.ignore-none { color: #999; font-weight: normal; }

.wrapper {
  min-height: 100%;
  height: auto !important;
  height: 100%;
  margin: 0 auto -48px;
}
.footer, .push {
  height: 48px;
}


================================================
FILE: coverage/lcov-report/block-navigation.js
================================================
/* eslint-disable */
var jumpToCode = (function init() {
    // Classes of code we would like to highlight in the file view
    var missingCoverageClasses = ['.cbranch-no', '.cstat-no', '.fstat-no'];

    // Elements to highlight in the file listing view
    var fileListingElements = ['td.pct.low'];

    // We don't want to select elements that are direct descendants of another match
    var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > `

    // Selecter that finds elements on the page to which we can jump
    var selector =
        fileListingElements.join(', ') +
        ', ' +
        notSelector +
        missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b`

    // The NodeList of matching elements
    var missingCoverageElements = document.querySelectorAll(selector);

    var currentIndex;

    function toggleClass(index) {
        missingCoverageElements
            .item(currentIndex)
            .classList.remove('highlighted');
        missingCoverageElements.item(index).classList.add('highlighted');
    }

    function makeCurrent(index) {
        toggleClass(index);
        currentIndex = index;
        missingCoverageElements.item(index).scrollIntoView({
            behavior: 'smooth',
            block: 'center',
            inline: 'center'
        });
    }

    function goToPrevious() {
        var nextIndex = 0;
        if (typeof currentIndex !== 'number' || currentIndex === 0) {
            nextIndex = missingCoverageElements.length - 1;
        } else if (missingCoverageElements.length > 1) {
            nextIndex = currentIndex - 1;
        }

        makeCurrent(nextIndex);
    }

    function goToNext() {
        var nextIndex = 0;

        if (
            typeof currentIndex === 'number' &&
            currentIndex < missingCoverageElements.length - 1
        ) {
            nextIndex = currentIndex + 1;
        }

        makeCurrent(nextIndex);
    }

    return function jump(event) {
        if (
            document.getElementById('fileSearch') === document.activeElement &&
            document.activeElement != null
        ) {
            // if we're currently focused on the search input, we don't want to navigate
            return;
        }

        switch (event.which) {
            case 78: // n
            case 74: // j
                goToNext();
                break;
            case 66: // b
            case 75: // k
            case 80: // p
                goToPrevious();
                break;
        }
    };
})();
window.addEventListener('keydown', jumpToCode);


================================================
FILE: coverage/lcov-report/index.html
================================================

<!doctype html>
<html lang="en">

<head>
    <title>Code coverage report for All files</title>
    <meta charset="utf-8" />
    <link rel="stylesheet" href="prettify.css" />
    <link rel="stylesheet" href="base.css" />
    <link rel="shortcut icon" type="image/x-icon" href="favicon.png" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style type='text/css'>
        .coverage-summary .sorter {
            background-image: url(sort-arrow-sprite.png);
        }
    </style>
</head>
    
<body>
<div class='wrapper'>
    <div class='pad1'>
        <h1>All files</h1>
        <div class='clearfix'>
            
            <div class='fl pad1y space-right2'>
                <span class="strong">Unknown% </span>
                <span class="quiet">Statements</span>
                <span class='fraction'>0/0</span>
            </div>
        
            
            <div class='fl pad1y space-right2'>
                <span class="strong">Unknown% </span>
                <span class="quiet">Branches</span>
                <span class='fraction'>0/0</span>
            </div>
        
            
            <div class='fl pad1y space-right2'>
                <span class="strong">Unknown% </span>
                <span class="quiet">Functions</span>
                <span class='fraction'>0/0</span>
            </div>
        
            
            <div class='fl pad1y space-right2'>
                <span class="strong">Unknown% </span>
                <span class="quiet">Lines</span>
                <span class='fraction'>0/0</span>
            </div>
        
            
        </div>
        <p class="quiet">
            Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
        </p>
        <template id="filterTemplate">
            <div class="quiet">
                Filter:
                <input oninput="onInput()" type="search" id="fileSearch">
            </div>
        </template>
    </div>
    <div class='status-line medium'></div>
    <div class="pad1">
<table class="coverage-summary">
<thead>
<tr>
   <th data-col="file" data-fmt="html" data-html="true" class="file">File</th>
   <th data-col="pic" data-type="number" data-fmt="html" data-html="true" class="pic"></th>
   <th data-col="statements" data-type="number" data-fmt="pct" class="pct">Statements</th>
   <th data-col="statements_raw" data-type="number" data-fmt="html" class="abs"></th>
   <th data-col="branches" data-type="number" data-fmt="pct" class="pct">Branches</th>
   <th data-col="branches_raw" data-type="number" data-fmt="html" class="abs"></th>
   <th data-col="functions" data-type="number" data-fmt="pct" class="pct">Functions</th>
   <th data-col="functions_raw" data-type="number" data-fmt="html" class="abs"></th>
   <th data-col="lines" data-type="number" data-fmt="pct" class="pct">Lines</th>
   <th data-col="lines_raw" data-type="number" data-fmt="html" class="abs"></th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
                <div class='push'></div><!-- for sticky footer -->
            </div><!-- /wrapper -->
            <div class='footer quiet pad2 space-top1 center small'>
                Code coverage generated by
                <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
                at Sun Jan 22 2023 22:55:15 GMT+0300 (GMT+03:00)
            </div>
        <script src="prettify.js"></script>
        <script>
            window.onload = function () {
                prettyPrint();
            };
        </script>
        <script src="sorter.js"></script>
        <script src="block-navigation.js"></script>
    </body>
</html>
    

================================================
FILE: coverage/lcov-report/prettify.css
================================================
.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}


================================================
FILE: coverage/lcov-report/prettify.js
================================================
/* eslint-disable */
window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V<U;++V){var ae=Z[V];if(ae.ignoreCase){ac=true}else{if(/[a-z]/i.test(ae.source.replace(/\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi,""))){S=true;ac=false;break}}}var Y={b:8,t:9,n:10,v:11,f:12,r:13};function ab(ah){var ag=ah.charCodeAt(0);if(ag!==92){return ag}var af=ah.charAt(1);ag=Y[af];if(ag){return ag}else{if("0"<=af&&af<="7"){return parseInt(ah.substring(1),8)}else{if(af==="u"||af==="x"){return parseInt(ah.substring(2),16)}else{return ah.charCodeAt(1)}}}}function T(af){if(af<32){return(af<16?"\\x0":"\\x")+af.toString(16)}var ag=String.fromCharCode(af);if(ag==="\\"||ag==="-"||ag==="["||ag==="]"){ag="\\"+ag}return ag}function X(am){var aq=am.substring(1,am.length-1).match(new RegExp("\\\\u[0-9A-Fa-f]{4}|\\\\x[0-9A-Fa-f]{2}|\\\\[0-3][0-7]{0,2}|\\\\[0-7]{1,2}|\\\\[\\s\\S]|-|[^-\\\\]","g"));var ak=[];var af=[];var ao=aq[0]==="^";for(var ar=ao?1:0,aj=aq.length;ar<aj;++ar){var ah=aq[ar];if(/\\[bdsw]/i.test(ah)){ak.push(ah)}else{var ag=ab(ah);var al;if(ar+2<aj&&"-"===aq[ar+1]){al=ab(aq[ar+2]);ar+=2}else{al=ag}af.push([ag,al]);if(!(al<65||ag>122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;ar<af.length;++ar){var at=af[ar];if(at[0]<=ap[1]+1){ap[1]=Math.max(ap[1],at[1])}else{ai.push(ap=at)}}var an=["["];if(ao){an.push("^")}an.push.apply(an,ak);for(var ar=0;ar<ai.length;++ar){var at=ai[ar];an.push(T(at[0]));if(at[1]>at[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak<ah;++ak){var ag=aj[ak];if(ag==="("){++am}else{if("\\"===ag.charAt(0)){var af=+ag.substring(1);if(af&&af<=am){an[af]=-1}}}}for(var ak=1;ak<an.length;++ak){if(-1===an[ak]){an[ak]=++ad}}for(var ak=0,am=0;ak<ah;++ak){var ag=aj[ak];if(ag==="("){++am;if(an[am]===undefined){aj[ak]="(?:"}}else{if("\\"===ag.charAt(0)){var af=+ag.substring(1);if(af&&af<=am){aj[ak]="\\"+an[am]}}}}for(var ak=0,am=0;ak<ah;++ak){if("^"===aj[ak]&&"^"!==aj[ak+1]){aj[ak]=""}}if(al.ignoreCase&&S){for(var ak=0;ak<ah;++ak){var ag=aj[ak];var ai=ag.charAt(0);if(ag.length>=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V<U;++V){var ae=Z[V];if(ae.global||ae.multiline){throw new Error(""+ae)}aa.push("(?:"+W(ae)+")")}return new RegExp(aa.join("|"),ac?"gi":"g")}function a(V){var U=/(?:^|\s)nocode(?:\s|$)/;var X=[];var T=0;var Z=[];var W=0;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=document.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Y=S&&"pre"===S.substring(0,3);function aa(ab){switch(ab.nodeType){case 1:if(U.test(ab.className)){return}for(var ae=ab.firstChild;ae;ae=ae.nextSibling){aa(ae)}var ad=ab.nodeName;if("BR"===ad||"LI"===ad){X[W]="\n";Z[W<<1]=T++;Z[(W++<<1)|1]=ab}break;case 3:case 4:var ac=ab.nodeValue;if(ac.length){if(!Y){ac=ac.replace(/[ \t\r\n]+/g," ")}else{ac=ac.replace(/\r\n?/g,"\n")}X[W]=ac;Z[W<<1]=T;T+=ac.length;Z[(W++<<1)|1]=ab}break}}aa(V);return{sourceCode:X.join("").replace(/\n$/,""),spans:Z}}function B(S,U,W,T){if(!U){return}var V={sourceCode:U,basePos:S};W(V);T.push.apply(T,V.decorations)}var v=/\S/;function o(S){var V=undefined;for(var U=S.firstChild;U;U=U.nextSibling){var T=U.nodeType;V=(T===1)?(V?S:U):(T===3)?(v.test(U.nodeValue)?S:V):V}return V===S?undefined:V}function g(U,T){var S={};var V;(function(){var ad=U.concat(T);var ah=[];var ag={};for(var ab=0,Z=ad.length;ab<Z;++ab){var Y=ad[ab];var ac=Y[3];if(ac){for(var ae=ac.length;--ae>=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae<aq;++ae){var ag=an[ae];var ap=aj[ag];var ai=void 0;var am;if(typeof ap==="string"){am=false}else{var aa=S[ag.charAt(0)];if(aa){ai=ag.match(aa[1]);ap=aa[0]}else{for(var ao=0;ao<X;++ao){aa=T[ao];ai=ag.match(aa[1]);if(ai){ap=aa[0];break}}if(!ai){ap=F}}am=ap.length>=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y<W.length;++Y){ae(W[Y])}if(ag===(ag|0)){W[0].setAttribute("value",ag)}var aa=ac.createElement("OL");aa.className="linenums";var X=Math.max(0,((ag-1))|0)||0;for(var Y=0,T=W.length;Y<T;++Y){af=W[Y];af.className="L"+((Y+X)%10);if(!af.firstChild){af.appendChild(ac.createTextNode("\xA0"))}aa.appendChild(af)}V.appendChild(aa)}function D(ac){var aj=/\bMSIE\b/.test(navigator.userAgent);var am=/\n/g;var al=ac.sourceCode;var an=al.length;var V=0;var aa=ac.spans;var T=aa.length;var ah=0;var X=ac.decorations;var Y=X.length;var Z=0;X[Y]=an;var ar,aq;for(aq=ar=0;aq<Y;){if(X[aq]!==X[aq+2]){X[ar++]=X[aq++];X[ar++]=X[aq++]}else{aq+=2}}Y=ar;for(aq=ar=0;aq<Y;){var at=X[aq];var ab=X[aq+1];var W=aq+2;while(W+2<=Y&&X[W+1]===ab){W+=2}X[ar++]=at;X[ar++]=ab;aq=W}Y=X.length=ar;var ae=null;while(ah<T){var af=aa[ah];var S=aa[ah+2]||an;var ag=X[Z];var ap=X[Z+2]||an;var W=Math.min(S,ap);var ak=aa[ah+1];var U;if(ak.nodeType!==1&&(U=al.substring(V,W))){if(aj){U=U.replace(am,"\r")}ak.nodeValue=U;var ai=ak.ownerDocument;var ao=ai.createElement("SPAN");ao.className=X[Z+1];var ad=ak.parentNode;ad.replaceChild(ao,ak);ao.appendChild(ak);if(V<S){aa[ah+1]=ak=ai.createTextNode(al.substring(W,S));ad.insertBefore(ak,ao.nextSibling)}}V=W;if(V>=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*</.test(S)?"default-markup":"default-code"}return t[T]}c(K,["default-code"]);c(g([],[[F,/^[^<?]+/],[E,/^<!\w[^>]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa<ac.length;++aa){for(var Z=0,V=ac[aa].length;Z<V;++Z){T.push(ac[aa][Z])}}ac=null;var W=Date;if(!W.now){W={now:function(){return +(new Date)}}}var X=0;var S;var ab=/\blang(?:uage)?-([\w.]+)(?!\S)/;var ae=/\bprettyprint\b/;function U(){var ag=(window.PR_SHOULD_USE_CONTINUATION?W.now()+250:Infinity);for(;X<T.length&&W.now()<ag;X++){var aj=T[X];var ai=aj.className;if(ai.indexOf("prettyprint")>=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X<T.length){setTimeout(U,250)}else{if(ad){ad()}}}U()}window.prettyPrintOne=y;window.prettyPrint=b;window.PR={createSimpleLexer:g,registerLangHandler:c,sourceDecorator:i,PR_ATTRIB_NAME:P,PR_ATTRIB_VALUE:n,PR_COMMENT:j,PR_DECLARATION:E,PR_KEYWORD:z,PR_LITERAL:G,PR_NOCODE:N,PR_PLAIN:F,PR_PUNCTUATION:L,PR_SOURCE:J,PR_STRING:C,PR_TAG:m,PR_TYPE:O}})();PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_DECLARATION,/^<!\w[^>]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^<script\b[^>]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:<!--|-->)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]);


================================================
FILE: coverage/lcov-report/sorter.js
================================================
/* eslint-disable */
var addSorting = (function() {
    'use strict';
    var cols,
        currentSort = {
            index: 0,
            desc: false
        };

    // returns the summary table element
    function getTable() {
        return document.querySelector('.coverage-summary');
    }
    // returns the thead element of the summary table
    function getTableHeader() {
        return getTable().querySelector('thead tr');
    }
    // returns the tbody element of the summary table
    function getTableBody() {
        return getTable().querySelector('tbody');
    }
    // returns the th element for nth column
    function getNthColumn(n) {
        return getTableHeader().querySelectorAll('th')[n];
    }

    function onFilterInput() {
        const searchValue = document.getElementById('fileSearch').value;
        const rows = document.getElementsByTagName('tbody')[0].children;
        for (let i = 0; i < rows.length; i++) {
            const row = rows[i];
            if (
                row.textContent
                    .toLowerCase()
                    .includes(searchValue.toLowerCase())
            ) {
                row.style.display = '';
            } else {
                row.style.display = 'none';
            }
        }
    }

    // loads the search box
    function addSearchBox() {
        var template = document.getElementById('filterTemplate');
        var templateClone = template.content.cloneNode(true);
        templateClone.getElementById('fileSearch').oninput = onFilterInput;
        template.parentElement.appendChild(templateClone);
    }

    // loads all columns
    function loadColumns() {
        var colNodes = getTableHeader().querySelectorAll('th'),
            colNode,
            cols = [],
            col,
            i;

        for (i = 0; i < colNodes.length; i += 1) {
            colNode = colNodes[i];
            col = {
                key: colNode.getAttribute('data-col'),
                sortable: !colNode.getAttribute('data-nosort'),
                type: colNode.getAttribute('data-type') || 'string'
            };
            cols.push(col);
            if (col.sortable) {
                col.defaultDescSort = col.type === 'number';
                colNode.innerHTML =
                    colNode.innerHTML + '<span class="sorter"></span>';
            }
        }
        return cols;
    }
    // attaches a data attribute to every tr element with an object
    // of data values keyed by column name
    function loadRowData(tableRow) {
        var tableCols = tableRow.querySelectorAll('td'),
            colNode,
            col,
            data = {},
            i,
            val;
        for (i = 0; i < tableCols.length; i += 1) {
            colNode = tableCols[i];
            col = cols[i];
            val = colNode.getAttribute('data-value');
            if (col.type === 'number') {
                val = Number(val);
            }
            data[col.key] = val;
        }
        return data;
    }
    // loads all row data
    function loadData() {
        var rows = getTableBody().querySelectorAll('tr'),
            i;

        for (i = 0; i < rows.length; i += 1) {
            rows[i].data = loadRowData(rows[i]);
        }
    }
    // sorts the table using the data for the ith column
    function sortByIndex(index, desc) {
        var key = cols[index].key,
            sorter = function(a, b) {
                a = a.data[key];
                b = b.data[key];
                return a < b ? -1 : a > b ? 1 : 0;
            },
            finalSorter = sorter,
            tableBody = document.querySelector('.coverage-summary tbody'),
            rowNodes = tableBody.querySelectorAll('tr'),
            rows = [],
            i;

        if (desc) {
            finalSorter = function(a, b) {
                return -1 * sorter(a, b);
            };
        }

        for (i = 0; i < rowNodes.length; i += 1) {
            rows.push(rowNodes[i]);
            tableBody.removeChild(rowNodes[i]);
        }

        rows.sort(finalSorter);

        for (i = 0; i < rows.length; i += 1) {
            tableBody.appendChild(rows[i]);
        }
    }
    // removes sort indicators for current column being sorted
    function removeSortIndicators() {
        var col = getNthColumn(currentSort.index),
            cls = col.className;

        cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, '');
        col.className = cls;
    }
    // adds sort indicators for current column being sorted
    function addSortIndicators() {
        getNthColumn(currentSort.index).className += currentSort.desc
            ? ' sorted-desc'
            : ' sorted';
    }
    // adds event listeners for all sorter widgets
    function enableUI() {
        var i,
            el,
            ithSorter = function ithSorter(i) {
                var col = cols[i];

                return function() {
                    var desc = col.defaultDescSort;

                    if (currentSort.index === i) {
                        desc = !currentSort.desc;
                    }
                    sortByIndex(i, desc);
                    removeSortIndicators();
                    currentSort.index = i;
                    currentSort.desc = desc;
                    addSortIndicators();
                };
            };
        for (i = 0; i < cols.length; i += 1) {
            if (cols[i].sortable) {
                // add the click event handler on the th so users
                // dont have to click on those tiny arrows
                el = getNthColumn(i).querySelector('.sorter').parentElement;
                if (el.addEventListener) {
                    el.addEventListener('click', ithSorter(i));
                } else {
                    el.attachEvent('onclick', ithSorter(i));
                }
            }
        }
    }
    // adds sorting functionality to the UI
    return function() {
        if (!getTable()) {
            return;
        }
        cols = loadColumns();
        loadData();
        addSearchBox();
        addSortIndicators();
        enableUI();
    };
})();

window.addEventListener('load', addSorting);


================================================
FILE: coverage/lcov.info
================================================


================================================
FILE: example/README.md
================================================
# Example Project

Clone the repo and run

```sh
yarn
```
and

```sh
cd example && yarn ios (or yarn android)
```
You can specify your streaming URL's on the `App.tsx` file.
```tsx
...
...
import MicrophoneSelectModal from './components/MicrophoneSelectModal';

const STREAM_URL = 'YOUR_STREAM_URL'; // ex: rtmp://a.rtmp.youtube.com/live2
const STREAM_NAME = 'YOUR_STREAM_NAME'; // ex: abcd-1234-abcd-1234-abcd

export default function App() {
...
...
```
## Contributing

See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow.

## License

MIT


================================================
FILE: example/android/app/build.gradle
================================================
apply plugin: "com.android.application"

import com.android.build.OutputFile
import org.apache.tools.ant.taskdefs.condition.Os

/**
 * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
 * and bundleReleaseJsAndAssets).
 * These basically call `react-native bundle` with the correct arguments during the Android build
 * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the
 * bundle directly from the development server. Below you can see all the possible configurations
 * and their defaults. If you decide to add a configuration block, make sure to add it before the
 * `apply from: "../../node_modules/react-native/react.gradle"` line.
 *
 * project.ext.react = [
 *   // the name of the generated asset file containing your JS bundle
 *   bundleAssetName: "index.android.bundle",
 *
 *   // the entry file for bundle generation
 *   entryFile: "index.android.js",
 *
 *   // https://reactnative.dev/docs/performance#enable-the-ram-format
 *   bundleCommand: "ram-bundle",
 *
 *   // whether to bundle JS and assets in debug mode
 *   bundleInDebug: false,
 *
 *   // whether to bundle JS and assets in release mode
 *   bundleInRelease: true,
 *
 *   // whether to bundle JS and assets in another build variant (if configured).
 *   // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants
 *   // The configuration property can be in the following formats
 *   //         'bundleIn${productFlavor}${buildType}'
 *   //         'bundleIn${buildType}'
 *   // bundleInFreeDebug: true,
 *   // bundleInPaidRelease: true,
 *   // bundleInBeta: true,
 *
 *   // whether to disable dev mode in custom build variants (by default only disabled in release)
 *   // for RtmpExample: to disable dev mode in the staging build type (if configured)
 *   devDisabledInStaging: true,
 *   // The configuration property can be in the following formats
 *   //         'devDisabledIn${productFlavor}${buildType}'
 *   //         'devDisabledIn${buildType}'
 *
 *   // the root of your project, i.e. where "package.json" lives
 *   root: "../../",
 *
 *   // where to put the JS bundle asset in debug mode
 *   jsBundleDirDebug: "$buildDir/intermediates/assets/debug",
 *
 *   // where to put the JS bundle asset in release mode
 *   jsBundleDirRelease: "$buildDir/intermediates/assets/release",
 *
 *   // where to put drawable resources / React Native assets, e.g. the ones you use via
 *   // require('./image.png')), in debug mode
 *   resourcesDirDebug: "$buildDir/intermediates/res/merged/debug",
 *
 *   // where to put drawable resources / React Native assets, e.g. the ones you use via
 *   // require('./image.png')), in release mode
 *   resourcesDirRelease: "$buildDir/intermediates/res/merged/release",
 *
 *   // by default the gradle tasks are skipped if none of the JS files or assets change; this means
 *   // that we don't look at files in android/ or ios/ to determine whether the tasks are up to
 *   // date; if you have any other folders that you want to ignore for performance reasons (gradle
 *   // indexes the entire tree), add them here. Alternatively, if you have JS files in android/
 *   // for RtmpExample, you might want to remove it from here.
 *   inputExcludes: ["android/**", "ios/**"],
 *
 *   // override which node gets called and with what additional arguments
 *   nodeExecutableAndArgs: ["node"],
 *
 *   // supply additional arguments to the packager
 *   extraPackagerArgs: []
 * ]
 */

project.ext.react = [
    enableHermes: false,  // clean and rebuild if changing
    entryFile: "index.tsx",
]

apply from: "../../node_modules/react-native/react.gradle"

/**
 * Set this to true to create two separate APKs instead of one:
 *   - An APK that only works on ARM devices
 *   - An APK that only works on x86 devices
 * The advantage is the size of the APK is reduced by about 4MB.
 * Upload all the APKs to the Play Store and people will download
 * the correct one based on the CPU architecture of their device.
 */
def enableSeparateBuildPerCPUArchitecture = false

/**
 * Run Proguard to shrink the Java bytecode in release builds.
 */
def enableProguardInReleaseBuilds = false

/**
 * The preferred build flavor of JavaScriptCore.
 *
 * For RtmpExample, to use the international variant, you can use:
 * `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
 *
 * The international variant includes ICU i18n library and necessary data
 * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
 * give correct results when using with locales other than en-US.  Note that
 * this variant is about 6MiB larger per architecture than default.
 */
def jscFlavor = 'org.webkit:android-jsc:+'

/**
 * Whether to enable the Hermes VM.
 *
 * This should be set on project.ext.react and mirrored here.  If it is not set
 * on project.ext.react, JavaScript will not be compiled to Hermes Bytecode
 * and the benefits of using Hermes will therefore be sharply reduced.
 */
def enableHermes = project.ext.react.get("enableHermes", false);

def reactNativeArchitectures() {
    def value = project.getProperties().get("reactNativeArchitectures")
    return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
}

android {
    ndkVersion rootProject.ext.ndkVersion

    compileSdkVersion rootProject.ext.compileSdkVersion

    defaultConfig {
        applicationId "com.example.reactnativertmp"
        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        versionCode 1
        versionName "1.0"

        buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
        if (isNewArchitectureEnabled()) {
            // We configure the CMake build only if you decide to opt-in for the New Architecture.
            externalNativeBuild {
                cmake {
                    arguments "-DPROJECT_BUILD_DIR=$buildDir",
                        "-DREACT_ANDROID_DIR=$rootDir/../node_modules/react-native/ReactAndroid",
                        "-DREACT_ANDROID_BUILD_DIR=$rootDir/../node_modules/react-native/ReactAndroid/build",
                        "-DNODE_MODULES_DIR=$rootDir/../node_modules",
                        "-DANDROID_STL=c++_shared"
                }
            }
            if (!enableSeparateBuildPerCPUArchitecture) {
                ndk {
                    abiFilters (*reactNativeArchitectures())
                }
            }
        }
    }

    if (isNewArchitectureEnabled()) {
        // We configure the NDK build only if you decide to opt-in for the New Architecture.
        externalNativeBuild {
            cmake {
                path "$projectDir/src/main/jni/CMakeLists.txt"
            }
        }
        def reactAndroidProjectDir = project(':ReactAndroid').projectDir
        def packageReactNdkDebugLibs = tasks.register("packageReactNdkDebugLibs", Copy) {
            dependsOn(":ReactAndroid:packageReactNdkDebugLibsForBuck")
            from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib")
            into("$buildDir/react-ndk/exported")
        }
        def packageReactNdkReleaseLibs = tasks.register("packageReactNdkReleaseLibs", Copy) {
            dependsOn(":ReactAndroid:packageReactNdkReleaseLibsForBuck")
            from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib")
            into("$buildDir/react-ndk/exported")
        }
        afterEvaluate {
            // If you wish to add a custom TurboModule or component locally,
            // you should uncomment this line.
            // preBuild.dependsOn("generateCodegenArtifactsFromSchema")
            preDebugBuild.dependsOn(packageReactNdkDebugLibs)
            preReleaseBuild.dependsOn(packageReactNdkReleaseLibs)
            // Due to a bug inside AGP, we have to explicitly set a dependency
            // between configureCMakeDebug* tasks and the preBuild tasks.
            // This can be removed once this is solved: https://issuetracker.google.com/issues/207403732
            configureCMakeRelWithDebInfo.dependsOn(preReleaseBuild)
            configureCMakeDebug.dependsOn(preDebugBuild)
            reactNativeArchitectures().each { architecture ->
                tasks.findByName("configureCMakeDebug[${architecture}]")?.configure {
                    dependsOn("preDebugBuild")
                }
                tasks.findByName("configureCMakeRelWithDebInfo[${architecture}]")?.configure {
                    dependsOn("preReleaseBuild")
                }
            }
        }
    }

    splits {
        abi {
            reset()
            enable enableSeparateBuildPerCPUArchitecture
            universalApk false  // If true, also generate a universal APK
            include (*reactNativeArchitectures())
        }
    }
    signingConfigs {
        debug {
            storeFile file('debug.keystore')
            storePassword 'android'
            keyAlias 'androiddebugkey'
            keyPassword 'android'
        }
    }
    buildTypes {
        debug {
            signingConfig signingConfigs.debug
        }
        release {
            // Caution! In production, you need to generate your own keystore file.
            // see https://reactnative.dev/docs/signed-apk-android.
            signingConfig signingConfigs.debug
            minifyEnabled enableProguardInReleaseBuilds
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
        }
    }
    // applicationVariants are e.g. debug, release
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            // For each separate APK per architecture, set a unique version code as described here:
            // https://developer.android.com/studio/build/configure-apk-splits.html
            def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
            def abi = output.getFilter(OutputFile.ABI)
            if (abi != null) {  // null for the universal-debug, universal-release variants
                output.versionCodeOverride =
                        defaultConfig.versionCode * 1000 + versionCodes.get(abi)
            }

        }
    }
}

dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    //noinspection GradleDynamicVersion
    implementation "com.facebook.react:react-native:+"  // From node_modules


    implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
    debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
      exclude group:'com.facebook.fbjni'
    }
    debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
        exclude group:'com.facebook.flipper'
        exclude group:'com.squareup.okhttp3', module:'okhttp'
    }
    debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") {
        exclude group:'com.facebook.flipper'
    }

    if (enableHermes) {
     //noinspection GradleDynamicVersion
        implementation("com.facebook.react:hermes-engine:+") { // From node_modules
            exclude group:'com.facebook.fbjni'
        }
    } else {
        implementation jscFlavor
    }

    implementation project(':reactnativertmp')
}


if (isNewArchitectureEnabled()) {
    // If new architecture is enabled, we let you build RN from source
    // Otherwise we fallback to a prebuilt .aar bundled in the NPM package.
    // This will be applied to all the imported transtitive dependency.
    configurations.all {
        resolutionStrategy.dependencySubstitution {
            substitute(module("com.facebook.react:react-native"))
                    .using(project(":ReactAndroid"))
                    .because("On New Architecture we're building React Native from source")
            substitute(module("com.facebook.react:hermes-engine"))
                    .using(project(":ReactAndroid:hermes-engine"))
                    .because("On New Architecture we're building Hermes from source")
        }
    }
}

// Run this once to be able to run the application with BUCK
// puts all compile dependencies into folder libs for BUCK to use
task copyDownloadableDepsToLibs(type: Copy) {
    from configurations.implementation
    into 'libs'
}

apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)

def isNewArchitectureEnabled() {
    // To opt-in for the New Architecture, you can either:
    // - Set `newArchEnabled` to true inside the `gradle.properties` file
    // - Invoke gradle with `-newArchEnabled=true`
    // - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true`
    return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
}

================================================
FILE: example/android/app/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:


================================================
FILE: example/android/app/src/debug/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
    <application
        android:usesCleartextTraffic="true"
        tools:targetApi="28"
        tools:ignore="GoogleAppIndexingWarning">
        <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" android:exported="false" />
    </application>
</manifest>


================================================
FILE: example/android/app/src/debug/java/com/example/reactnativertmp/ReactNativeFlipper.java
================================================
/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * <p>This source code is licensed under the MIT license found in the LICENSE file in the root
 * directory of this source tree.
 */
package com.example.reactnativertmp;

import android.content.Context;
import com.facebook.flipper.android.AndroidFlipperClient;
import com.facebook.flipper.android.utils.FlipperUtils;
import com.facebook.flipper.core.FlipperClient;
import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin;
import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin;
import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin;
import com.facebook.flipper.plugins.inspector.DescriptorMapping;
import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin;
import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor;
import com.facebook.flipper.plugins.network.NetworkFlipperPlugin;
import com.facebook.flipper.plugins.react.ReactFlipperPlugin;
import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin;
import com.facebook.react.ReactInstanceEventListener;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.modules.network.NetworkingModule;
import okhttp3.OkHttpClient;

public class ReactNativeFlipper {
  public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
    if (FlipperUtils.shouldEnableFlipper(context)) {
      final FlipperClient client = AndroidFlipperClient.getInstance(context);
      client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults()));
      client.addPlugin(new ReactFlipperPlugin());
      client.addPlugin(new DatabasesFlipperPlugin(context));
      client.addPlugin(new SharedPreferencesFlipperPlugin(context));
      client.addPlugin(CrashReporterPlugin.getInstance());
      NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin();
      NetworkingModule.setCustomClientBuilder(
          new NetworkingModule.CustomClientBuilder() {
            @Override
            public void apply(OkHttpClient.Builder builder) {
              builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin));
            }
          });
      client.addPlugin(networkFlipperPlugin);
      client.start();
      // Fresco Plugin needs to ensure that ImagePipelineFactory is initialized
      // Hence we run if after all native modules have been initialized
      ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
      if (reactContext == null) {
        reactInstanceManager.addReactInstanceEventListener(
            new ReactInstanceEventListener() {
              @Override
              public void onReactContextInitialized(ReactContext reactContext) {
                reactInstanceManager.removeReactInstanceEventListener(this);
                reactContext.runOnNativeModulesQueueThread(
                    new Runnable() {
                      @Override
                      public void run() {
                        client.addPlugin(new FrescoFlipperPlugin());
                      }
                    });
              }
            });
      } else {
        client.addPlugin(new FrescoFlipperPlugin());
      }
    }
  }
}


================================================
FILE: example/android/app/src/main/AndroidManifest.xml
================================================
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.example.reactnativertmp">

  <uses-permission android:name="android.permission.INTERNET" />
  <uses-permission android:name="android.permission.CAMERA" />
  <uses-permission android:name="android.permission.RECORD_AUDIO" />
  <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />

  <application android:name=".MainApplication" android:label="@string/app_name"
    android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round"
    android:allowBackup="false" android:theme="@style/AppTheme">
    <activity android:name=".MainActivity" android:label="@string/app_name"
      android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
      android:launchMode="singleTask" android:windowSoftInputMode="adjustResize"
      android:exported="true">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>
    <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
  </application>

</manifest>

================================================
FILE: example/android/app/src/main/java/com/example/reactnativertmp/MainActivity.java
================================================
package com.example.reactnativertmp;

import com.facebook.react.ReactActivity;
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.ReactRootView;

public class MainActivity extends ReactActivity {

  /**
   * Returns the name of the main component registered from JavaScript. This is used to schedule
   * rendering of the component.
   */
  @Override
  protected String getMainComponentName() {
    return "RtmpExample";
  }

  /**
   * Returns the instance of the {@link ReactActivityDelegate}. There the RootView is created and
   * you can specify the renderer you wish to use - the new renderer (Fabric) or the old renderer
   * (Paper).
   */
  @Override
  protected ReactActivityDelegate createReactActivityDelegate() {
    return new MainActivityDelegate(this, getMainComponentName());
  }
  public static class MainActivityDelegate extends ReactActivityDelegate {
    public MainActivityDelegate(ReactActivity activity, String mainComponentName) {
      super(activity, mainComponentName);
    }
    @Override
    protected ReactRootView createRootView() {
      ReactRootView reactRootView = new ReactRootView(getContext());
      // If you opted-in for the New Architecture, we enable the Fabric Renderer.
      reactRootView.setIsFabric(BuildConfig.IS_NEW_ARCHITECTURE_ENABLED);
      return reactRootView;
    }
    @Override
    protected boolean isConcurrentRootEnabled() {
      // If you opted-in for the New Architecture, we enable Concurrent Root (i.e. React 18).
      // More on this on https://reactjs.org/blog/2022/03/29/react-v18.html
      return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
    }
  }
}


================================================
FILE: example/android/app/src/main/java/com/example/reactnativertmp/MainApplication.java
================================================
package com.example.reactnativertmp;

import android.app.Application;
import android.content.Context;
import com.facebook.react.PackageList;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.config.ReactFeatureFlags;
import com.facebook.soloader.SoLoader;
import com.example.reactnativertmp.newarchitecture.MainApplicationReactNativeHost;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import com.reactnativertmppublisher.RTMPPackage;

public class MainApplication extends Application implements ReactApplication {

  private final ReactNativeHost mReactNativeHost =
      new ReactNativeHost(this) {
        @Override
        public boolean getUseDeveloperSupport() {
          return BuildConfig.DEBUG;
        }

        @Override
        protected List<ReactPackage> getPackages() {
          @SuppressWarnings("UnnecessaryLocalVariable")
          List<ReactPackage> packages = new PackageList(this).getPackages();
          // Packages that cannot be autolinked yet can be added manually here, for RtmpExample:
          // packages.add(new MyReactNativePackage());
          packages.add(new RTMPPackage());
          return packages;
        }

        @Override
        protected String getJSMainModuleName() {
          return "index";
        }
      };

  private final ReactNativeHost mNewArchitectureNativeHost =
      new MainApplicationReactNativeHost(this);

  @Override
  public ReactNativeHost getReactNativeHost() {
    if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
      return mNewArchitectureNativeHost;
    } else {
      return mReactNativeHost;
    }
  }

  @Override
  public void onCreate() {
    super.onCreate();
    // If you opted-in for the New Architecture, we enable the TurboModule system
    ReactFeatureFlags.useTurboModules = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
    SoLoader.init(this, /* native exopackage */ false);
    initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); // Remove this line if you don't want Flipper enabled
  }

  /**
   * Loads Flipper in React Native templates.
   *
   * @param context
   */
  private static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
    if (BuildConfig.DEBUG) {
      try {
        /*
         We use reflection here to pick up the class that initializes Flipper,
        since Flipper library is not available in release mode
        */
        Class<?> aClass = Class.forName("com.example.reactnativertmp.ReactNativeFlipper");
        aClass
            .getMethod("initializeFlipper", Context.class, ReactInstanceManager.class)
            .invoke(null, context, reactInstanceManager);
      } catch (ClassNotFoundException e) {
        e.printStackTrace();
      } catch (NoSuchMethodException e) {
        e.printStackTrace();
      } catch (IllegalAccessException e) {
        e.printStackTrace();
      } catch (InvocationTargetException e) {
        e.printStackTrace();
      }
    }
  }
}


================================================
FILE: example/android/app/src/main/java/com/example/reactnativertmp/newarchitecture/MainApplicationReactNativeHost.java
================================================
package com.example.reactnativertmp.newarchitecture;

import android.app.Application;
import androidx.annotation.NonNull;
import com.facebook.react.PackageList;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.ReactPackageTurboModuleManagerDelegate;
import com.facebook.react.bridge.JSIModulePackage;
import com.facebook.react.bridge.JSIModuleProvider;
import com.facebook.react.bridge.JSIModuleSpec;
import com.facebook.react.bridge.JSIModuleType;
import com.facebook.react.bridge.JavaScriptContextHolder;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.UIManager;
import com.facebook.react.fabric.ComponentFactory;
import com.facebook.react.fabric.CoreComponentsRegistry;
import com.facebook.react.fabric.FabricJSIModuleProvider;
import com.facebook.react.fabric.ReactNativeConfig;
import com.facebook.react.uimanager.ViewManagerRegistry;
import com.example.reactnativertmp.BuildConfig;
import com.example.reactnativertmp.newarchitecture.components.MainComponentsRegistry;
import com.example.reactnativertmp.newarchitecture.modules.MainApplicationTurboModuleManagerDelegate;
import java.util.ArrayList;
import java.util.List;

/**
 * A {@link ReactNativeHost} that helps you load everything needed for the New Architecture, both
 * TurboModule delegates and the Fabric Renderer.
 *
 * <p>Please note that this class is used ONLY if you opt-in for the New Architecture (see the
 * `newArchEnabled` property). Is ignored otherwise.
 */
public class MainApplicationReactNativeHost extends ReactNativeHost {
  public MainApplicationReactNativeHost(Application application) {
    super(application);
  }

  @Override
  public boolean getUseDeveloperSupport() {
    return BuildConfig.DEBUG;
  }

  @Override
  protected List<ReactPackage> getPackages() {
    List<ReactPackage> packages = new PackageList(this).getPackages();
    // Packages that cannot be autolinked yet can be added manually here, for example:
    //     packages.add(new MyReactNativePackage());
    // TurboModules must also be loaded here providing a valid TurboReactPackage implementation:
    //     packages.add(new TurboReactPackage() { ... });
    // If you have custom Fabric Components, their ViewManagers should also be loaded here
    // inside a ReactPackage.
    return packages;
  }

  @Override
  protected String getJSMainModuleName() {
    return "index";
  }

  @NonNull
  @Override
  protected ReactPackageTurboModuleManagerDelegate.Builder
      getReactPackageTurboModuleManagerDelegateBuilder() {
    // Here we provide the ReactPackageTurboModuleManagerDelegate Builder. This is necessary
    // for the new architecture and to use TurboModules correctly.
    return new MainApplicationTurboModuleManagerDelegate.Builder();
  }

  @Override
  protected JSIModulePackage getJSIModulePackage() {
    return new JSIModulePackage() {
      @Override
      public List<JSIModuleSpec> getJSIModules(
          final ReactApplicationContext reactApplicationContext,
          final JavaScriptContextHolder jsContext) {
        final List<JSIModuleSpec> specs = new ArrayList<>();

        // Here we provide a new JSIModuleSpec that will be responsible of providing the
        // custom Fabric Components.
        specs.add(
            new JSIModuleSpec() {
              @Override
              public JSIModuleType getJSIModuleType() {
                return JSIModuleType.UIManager;
              }

              @Override
              public JSIModuleProvider<UIManager> getJSIModuleProvider() {
                final ComponentFactory componentFactory = new ComponentFactory();
                CoreComponentsRegistry.register(componentFactory);

                // Here we register a Components Registry.
                // The one that is generated with the template contains no components
                // and just provides you the one from React Native core.
                MainComponentsRegistry.register(componentFactory);

                final ReactInstanceManager reactInstanceManager = getReactInstanceManager();

                ViewManagerRegistry viewManagerRegistry =
                    new ViewManagerRegistry(
                        reactInstanceManager.getOrCreateViewManagers(reactApplicationContext));

                return new FabricJSIModuleProvider(
                    reactApplicationContext,
                    componentFactory,
                    ReactNativeConfig.DEFAULT_CONFIG,
                    viewManagerRegistry);
              }
            });
        return specs;
      }
    };
  }
}


================================================
FILE: example/android/app/src/main/java/com/example/reactnativertmp/newarchitecture/components/MainComponentsRegistry.java
================================================
package com.example.reactnativertmp.newarchitecture.components;

import com.facebook.jni.HybridData;
import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.react.fabric.ComponentFactory;
import com.facebook.soloader.SoLoader;

/**
 * Class responsible to load the custom Fabric Components. This class has native methods and needs a
 * corresponding C++ implementation/header file to work correctly (already placed inside the jni/
 * folder for you).
 *
 * <p>Please note that this class is used ONLY if you opt-in for the New Architecture (see the
 * `newArchEnabled` property). Is ignored otherwise.
 */
@DoNotStrip
public class MainComponentsRegistry {
  static {
    SoLoader.loadLibrary("fabricjni");
  }

  @DoNotStrip private final HybridData mHybridData;

  @DoNotStrip
  private native HybridData initHybrid(ComponentFactory componentFactory);

  @DoNotStrip
  private MainComponentsRegistry(ComponentFactory componentFactory) {
    mHybridData = initHybrid(componentFactory);
  }

  @DoNotStrip
  public static MainComponentsRegistry register(ComponentFactory componentFactory) {
    return new MainComponentsRegistry(componentFactory);
  }
}


================================================
FILE: example/android/app/src/main/java/com/example/reactnativertmp/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java
================================================
package com.example.reactnativertmp.newarchitecture.modules;

import com.facebook.jni.HybridData;
import com.facebook.react.ReactPackage;
import com.facebook.react.ReactPackageTurboModuleManagerDelegate;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.soloader.SoLoader;
import java.util.List;

/**
 * Class responsible to load the TurboModules. This class has native methods and needs a
 * corresponding C++ implementation/header file to work correctly (already placed inside the jni/
 * folder for you).
 *
 * <p>Please note that this class is used ONLY if you opt-in for the New Architecture (see the
 * `newArchEnabled` property). Is ignored otherwise.
 */
public class MainApplicationTurboModuleManagerDelegate
    extends ReactPackageTurboModuleManagerDelegate {

  private static volatile boolean sIsSoLibraryLoaded;

  protected MainApplicationTurboModuleManagerDelegate(
      ReactApplicationContext reactApplicationContext, List<ReactPackage> packages) {
    super(reactApplicationContext, packages);
  }

  protected native HybridData initHybrid();

  native boolean canCreateTurboModule(String moduleName);

  public static class Builder extends ReactPackageTurboModuleManagerDelegate.Builder {
    protected MainApplicationTurboModuleManagerDelegate build(
        ReactApplicationContext context, List<ReactPackage> packages) {
      return new MainApplicationTurboModuleManagerDelegate(context, packages);
    }
  }

  @Override
  protected synchronized void maybeLoadOtherSoLibraries() {
    if (!sIsSoLibraryLoaded) {
      // If you change the name of your application .so file in the Android.mk file,
      // make sure you update the name here as well.
      SoLoader.loadLibrary("reactnativertmp_appmodules");
      sIsSoLibraryLoaded = true;
    }
  }
}


================================================
FILE: example/android/app/src/main/jni/CMakeLists.txt
================================================
cmake_minimum_required(VERSION 3.13)

# Define the library name here.
project(reactnativertmp_appmodules)

# This file includes all the necessary to let you build your application with the New Architecture.
include(${REACT_ANDROID_DIR}/cmake-utils/ReactNative-application.cmake)


================================================
FILE: example/android/app/src/main/jni/MainApplicationModuleProvider.cpp
================================================
#include "MainApplicationModuleProvider.h"

#include <rncli.h>
#include <rncore.h>

namespace facebook {
namespace react {

std::shared_ptr<TurboModule> MainApplicationModuleProvider(
    const std::string &moduleName,
    const JavaTurboModule::InitParams &params) {
  // Here you can provide your own module provider for TurboModules coming from
  // either your application or from external libraries. The approach to follow
  // is similar to the following (for a library called `samplelibrary`:
  //
  // auto module = samplelibrary_ModuleProvider(moduleName, params);
  // if (module != nullptr) {
  //    return module;
  // }
  // return rncore_ModuleProvider(moduleName, params);

  // Module providers autolinked by RN CLI
  auto rncli_module = rncli_ModuleProvider(moduleName, params);
  if (rncli_module != nullptr) {
    return rncli_module;
  }

  return rncore_ModuleProvider(moduleName, params);
}

} // namespace react
} // namespace facebook


================================================
FILE: example/android/app/src/main/jni/MainApplicationModuleProvider.h
================================================
#pragma once

#include <memory>
#include <string>

#include <ReactCommon/JavaTurboModule.h>

namespace facebook {
namespace react {

std::shared_ptr<TurboModule> MainApplicationModuleProvider(
    const std::string &moduleName,
    const JavaTurboModule::InitParams &params);

} // namespace react
} // namespace facebook


================================================
FILE: example/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp
================================================
#include "MainApplicationTurboModuleManagerDelegate.h"
#include "MainApplicationModuleProvider.h"

namespace facebook {
namespace react {

jni::local_ref<MainApplicationTurboModuleManagerDelegate::jhybriddata>
MainApplicationTurboModuleManagerDelegate::initHybrid(
    jni::alias_ref<jhybridobject>) {
  return makeCxxInstance();
}

void MainApplicationTurboModuleManagerDelegate::registerNatives() {
  registerHybrid({
      makeNativeMethod(
          "initHybrid", MainApplicationTurboModuleManagerDelegate::initHybrid),
      makeNativeMethod(
          "canCreateTurboModule",
          MainApplicationTurboModuleManagerDelegate::canCreateTurboModule),
  });
}

std::shared_ptr<TurboModule>
MainApplicationTurboModuleManagerDelegate::getTurboModule(
    const std::string &name,
    const std::shared_ptr<CallInvoker> &jsInvoker) {
  // Not implemented yet: provide pure-C++ NativeModules here.
  return nullptr;
}

std::shared_ptr<TurboModule>
MainApplicationTurboModuleManagerDelegate::getTurboModule(
    const std::string &name,
    const JavaTurboModule::InitParams &params) {
  return MainApplicationModuleProvider(name, params);
}

bool MainApplicationTurboModuleManagerDelegate::canCreateTurboModule(
    const std::string &name) {
  return getTurboModule(name, nullptr) != nullptr ||
      getTurboModule(name, {.moduleName = name}) != nullptr;
}

} // namespace react
} // namespace facebook


================================================
FILE: example/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h
================================================
#include <memory>
#include <string>

#include <ReactCommon/TurboModuleManagerDelegate.h>
#include <fbjni/fbjni.h>

namespace facebook {
namespace react {

class MainApplicationTurboModuleManagerDelegate
    : public jni::HybridClass<
          MainApplicationTurboModuleManagerDelegate,
          TurboModuleManagerDelegate> {
 public:
  // Adapt it to the package you used for your Java class.
  static constexpr auto kJavaDescriptor =
      "Lcom/example/reactnativertmp/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate;";

  static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jhybridobject>);

  static void registerNatives();

  std::shared_ptr<TurboModule> getTurboModule(
      const std::string &name,
      const std::shared_ptr<CallInvoker> &jsInvoker) override;
  std::shared_ptr<TurboModule> getTurboModule(
      const std::string &name,
      const JavaTurboModule::InitParams &params) override;

  /**
   * Test-only method. Allows user to verify whether a TurboModule can be
   * created by instances of this class.
   */
  bool canCreateTurboModule(const std::string &name);
};

} // namespace react
} // namespace facebook


================================================
FILE: example/android/app/src/main/jni/MainComponentsRegistry.cpp
================================================
#include "MainComponentsRegistry.h"

#include <CoreComponentsRegistry.h>
#include <fbjni/fbjni.h>
#include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
#include <react/renderer/components/rncore/ComponentDescriptors.h>
#include <rncli.h>

namespace facebook {
namespace react {

MainComponentsRegistry::MainComponentsRegistry(ComponentFactory *delegate) {}

std::shared_ptr<ComponentDescriptorProviderRegistry const>
MainComponentsRegistry::sharedProviderRegistry() {
  auto providerRegistry = CoreComponentsRegistry::sharedProviderRegistry();

  // Autolinked providers registered by RN CLI
  rncli_registerProviders(providerRegistry);

  // Custom Fabric Components go here. You can register custom
  // components coming from your App or from 3rd party libraries here.
  //
  // providerRegistry->add(concreteComponentDescriptorProvider<
  //        AocViewerComponentDescriptor>());
  return providerRegistry;
}

jni::local_ref<MainComponentsRegistry::jhybriddata>
MainComponentsRegistry::initHybrid(
    jni::alias_ref<jclass>,
    ComponentFactory *delegate) {
  auto instance = makeCxxInstance(delegate);

  auto buildRegistryFunction =
      [](EventDispatcher::Weak const &eventDispatcher,
         ContextContainer::Shared const &contextContainer)
      -> ComponentDescriptorRegistry::Shared {
    auto registry = MainComponentsRegistry::sharedProviderRegistry()
                        ->createComponentDescriptorRegistry(
                            {eventDispatcher, contextContainer});

    auto mutableRegistry =
        std::const_pointer_cast<ComponentDescriptorRegistry>(registry);

    mutableRegistry->setFallbackComponentDescriptor(
        std::make_shared<UnimplementedNativeViewComponentDescriptor>(
            ComponentDescriptorParameters{
                eventDispatcher, contextContainer, nullptr}));

    return registry;
  };

  delegate->buildRegistryFunction = buildRegistryFunction;
  return instance;
}

void MainComponentsRegistry::registerNatives() {
  registerHybrid({
      makeNativeMethod("initHybrid", MainComponentsRegistry::initHybrid),
  });
}

} // namespace react
} // namespace facebook


================================================
FILE: example/android/app/src/main/jni/MainComponentsRegistry.h
================================================
#pragma once

#include <ComponentFactory.h>
#include <fbjni/fbjni.h>
#include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
#include <react/renderer/componentregistry/ComponentDescriptorRegistry.h>

namespace facebook {
namespace react {

class MainComponentsRegistry
    : public facebook::jni::HybridClass<MainComponentsRegistry> {
 public:
  // Adapt it to the package you used for your Java class.
  constexpr static auto kJavaDescriptor =
      "Lcom/example/reactnativertmp/newarchitecture/components/MainComponentsRegistry;";

  static void registerNatives();

  MainComponentsRegistry(ComponentFactory *delegate);

 private:
  static std::shared_ptr<ComponentDescriptorProviderRegistry const>
  sharedProviderRegistry();

  static jni::local_ref<jhybriddata> initHybrid(
      jni::alias_ref<jclass>,
      ComponentFactory *delegate);
};

} // namespace react
} // namespace facebook


================================================
FILE: example/android/app/src/main/jni/OnLoad.cpp
================================================
#include <fbjni/fbjni.h>
#include "MainApplicationTurboModuleManagerDelegate.h"
#include "MainComponentsRegistry.h"

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
  return facebook::jni::initialize(vm, [] {
    facebook::react::MainApplicationTurboModuleManagerDelegate::
        registerNatives();
    facebook::react::MainComponentsRegistry::registerNatives();
  });
}


================================================
FILE: example/android/app/src/main/res/drawable/rn_edit_text_material.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014 The Android Open Source Project

     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

          http://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.
-->
<inset xmlns:android="http://schemas.android.com/apk/res/android"
       android:insetLeft="@dimen/abc_edit_text_inset_horizontal_material"
       android:insetRight="@dimen/abc_edit_text_inset_horizontal_material"
       android:insetTop="@dimen/abc_edit_text_inset_top_material"
       android:insetBottom="@dimen/abc_edit_text_inset_bottom_material">

    <selector>
        <!-- 
          This file is a copy of abc_edit_text_material (https://bit.ly/3k8fX7I).
          The item below with state_pressed="false" and state_focused="false" causes a NullPointerException.
          NullPointerException:tempt to invoke virtual method 'android.graphics.drawable.Drawable android.graphics.drawable.Drawable$ConstantState.newDrawable(android.content.res.Resources)'

          <item android:state_pressed="false" android:state_focused="false" android:drawable="@drawable/abc_textfield_default_mtrl_alpha"/>

          For more info, see https://bit.ly/3CdLStv (react-native/pull/29452) and https://bit.ly/3nxOMoR.
        -->
        <item android:state_enabled="false" android:drawable="@drawable/abc_textfield_default_mtrl_alpha"/>
        <item android:drawable="@drawable/abc_textfield_activated_mtrl_alpha"/>
    </selector>

</inset>


================================================
FILE: example/android/app/src/main/res/values/strings.xml
================================================
<resources>
    <string name="app_name">Rtmp Example</string>
</resources>


================================================
FILE: example/android/app/src/main/res/values/styles.xml
================================================
<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="android:editTextBackground">@drawable/rn_edit_text_material</item>
    </style>

</resources>


================================================
FILE: example/android/build.gradle
================================================
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    ext {
        buildToolsVersion = "31.0.0"
        minSdkVersion = 21
        compileSdkVersion = 31
        targetSdkVersion = 31
        if (System.properties['os.arch'] == "aarch64") {
            // For M1 Users we need to use the NDK 24 which added support for aarch64
            ndkVersion = "24.0.8215888"
        } else {
            // Otherwise we default to the side-by-side NDK version from AGP.
            ndkVersion = "21.4.7075529"
        }
    }
    repositories {
        google()
        mavenCentral()
//        jcenter()
    }
    dependencies {
        classpath("com.android.tools.build:gradle:7.2.1")
        classpath("com.facebook.react:react-native-gradle-plugin")
        classpath("de.undercouch:gradle-download-task:5.0.1")
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
//        mavenLocal()
        maven {
            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
            url("$rootDir/../node_modules/react-native/android")
        }
        maven {
            // Android JSC is installed from npm
            url("$rootDir/../node_modules/jsc-android/dist")
        }
        mavenCentral {
            // We don't want to fetch react-native from Maven Central as there are
            // older versions over there.
            content {
                excludeGroup "com.facebook.react"
            }
        }
        google()
        mavenCentral()
//      jcenter()
        maven { url 'https://www.jitpack.io' }
    }
}


================================================
FILE: example/android/gradle/wrapper/gradle-wrapper.properties
================================================
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists


================================================
FILE: example/android/gradle.properties
================================================
# Project-wide Gradle settings.

# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.

# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html

# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx512m -XX:MaxMetaspaceSize=256m
org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m

# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true

android.useAndroidX=true
android.enableJetifier=true
FLIPPER_VERSION=0.125.0
# Use this property to specify which architecture you want to build.
# You can also override it from the CLI using
# ./gradlew <task> -PreactNativeArchitectures=x86_64
reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
# Use this property to enable support to the new architecture.
# This will allow you to use TurboModules and the Fabric render in
# your application. You should enable this flag either if you want
# to write custom TurboModules/Fabric components OR use libraries that
# are providing them.
newArchEnabled=false

================================================
FILE: example/android/gradlew
================================================
#!/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 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
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

APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit

APP_NAME="Gradle"
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='"-Xmx64m" "-Xms64m"'

# Use the maximum available, or set MAX_FD != -1 to use that value.
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  ;; #(
  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
    else
        JAVACMD=$JAVA_HOME/bin/java
    fi
    if [ ! -x "$JAVACMD" ] ; then
        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
    fi
else
    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
location of your Java installation."
fi

# Increase the maximum file descriptors if we can.
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

# 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.

# 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" )

    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" "$@"

================================================
FILE: example/android/gradlew.bat
================================================
@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
@rem  Gradle startup script for Windows
@rem
@rem ##########################################################################

@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal

set DIRNAME=%~dp0
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="-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 execute

echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe

if exist "%JAVA_EXE%" goto execute

echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

: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 %*

:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd

:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1

:mainEnd
if "%OS%"=="Windows_NT" endlocal

:omega

================================================
FILE: example/android/settings.gradle
================================================
rootProject.name = 'RtmpExample'
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
include ':app'
includeBuild('../node_modules/react-native-gradle-plugin')
if (settings.hasProperty("newArchEnabled") && settings.newArchEnabled == "true") {
    include(":ReactAndroid")
    project(":ReactAndroid").projectDir = file('../node_modules/react-native/ReactAndroid')
    include(":ReactAndroid:hermes-engine")
    project(":ReactAndroid:hermes-engine").projectDir = file('../node_modules/react-native/ReactAndroid/hermes-engine')
}
include ':reactnativertmp'
project(':reactnativertmp').projectDir = new File(rootProject.projectDir, '../../android')


================================================
FILE: example/app.json
================================================
{
  "name": "RtmpExample",
  "displayName": "Rtmp Example"
}


================================================
FILE: example/babel.config.js
================================================
const path = require('path');
const pak = require('../package.json');

module.exports = {
  presets: ['module:metro-react-native-babel-
Download .txt
gitextract_iogv7721/

├── .editorconfig
├── .gitattributes
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.yml
│   │   └── feature_request.md
│   └── workflows/
│       └── build.yml
├── .gitignore
├── .husky/
│   ├── .npmignore
│   ├── commit-msg
│   └── pre-commit
├── .yarnrc
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── __mocks__/
│   └── RTMPPublisher.js
├── android/
│   ├── build.gradle
│   ├── gradle/
│   │   └── wrapper/
│   │       ├── gradle-wrapper.jar
│   │       └── gradle-wrapper.properties
│   ├── gradlew
│   ├── gradlew.bat
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           └── java/
│               └── com/
│                   └── reactnativertmppublisher/
│                       ├── RTMPManager.java
│                       ├── RTMPModule.java
│                       ├── RTMPPackage.java
│                       ├── enums/
│                       │   ├── AudioInputType.java
│                       │   ├── BluetoothDeviceStatuses.java
│                       │   └── StreamState.java
│                       ├── interfaces/
│                       │   └── ConnectionListener.java
│                       ├── modules/
│                       │   ├── BluetoothDeviceConnector.java
│                       │   ├── ConnectionChecker.java
│                       │   ├── Publisher.java
│                       │   └── SurfaceHolderHelper.java
│                       └── utils/
│                           └── ObjectCaster.java
├── babel.config.js
├── coverage/
│   ├── clover.xml
│   ├── coverage-final.json
│   ├── lcov-report/
│   │   ├── Component.tsx.html
│   │   ├── RTMPPublisher.tsx.html
│   │   ├── base.css
│   │   ├── block-navigation.js
│   │   ├── index.html
│   │   ├── prettify.css
│   │   ├── prettify.js
│   │   └── sorter.js
│   └── lcov.info
├── example/
│   ├── README.md
│   ├── android/
│   │   ├── app/
│   │   │   ├── build.gradle
│   │   │   ├── debug.keystore
│   │   │   ├── proguard-rules.pro
│   │   │   └── src/
│   │   │       ├── debug/
│   │   │       │   ├── AndroidManifest.xml
│   │   │       │   └── java/
│   │   │       │       └── com/
│   │   │       │           └── example/
│   │   │       │               └── reactnativertmp/
│   │   │       │                   └── ReactNativeFlipper.java
│   │   │       └── main/
│   │   │           ├── AndroidManifest.xml
│   │   │           ├── java/
│   │   │           │   └── com/
│   │   │           │       └── example/
│   │   │           │           └── reactnativertmp/
│   │   │           │               ├── MainActivity.java
│   │   │           │               ├── MainApplication.java
│   │   │           │               └── newarchitecture/
│   │   │           │                   ├── MainApplicationReactNativeHost.java
│   │   │           │                   ├── components/
│   │   │           │                   │   └── MainComponentsRegistry.java
│   │   │           │                   └── modules/
│   │   │           │                       └── MainApplicationTurboModuleManagerDelegate.java
│   │   │           ├── jni/
│   │   │           │   ├── CMakeLists.txt
│   │   │           │   ├── MainApplicationModuleProvider.cpp
│   │   │           │   ├── MainApplicationModuleProvider.h
│   │   │           │   ├── MainApplicationTurboModuleManagerDelegate.cpp
│   │   │           │   ├── MainApplicationTurboModuleManagerDelegate.h
│   │   │           │   ├── MainComponentsRegistry.cpp
│   │   │           │   ├── MainComponentsRegistry.h
│   │   │           │   └── OnLoad.cpp
│   │   │           └── res/
│   │   │               ├── drawable/
│   │   │               │   └── rn_edit_text_material.xml
│   │   │               └── values/
│   │   │                   ├── strings.xml
│   │   │                   └── styles.xml
│   │   ├── build.gradle
│   │   ├── gradle/
│   │   │   └── wrapper/
│   │   │       ├── gradle-wrapper.jar
│   │   │       └── gradle-wrapper.properties
│   │   ├── gradle.properties
│   │   ├── gradlew
│   │   ├── gradlew.bat
│   │   └── settings.gradle
│   ├── app.json
│   ├── babel.config.js
│   ├── index.tsx
│   ├── ios/
│   │   ├── .xcode.env
│   │   ├── File.swift
│   │   ├── Podfile
│   │   ├── RtmpExample/
│   │   │   ├── AppDelegate.h
│   │   │   ├── AppDelegate.mm
│   │   │   ├── Images.xcassets/
│   │   │   │   ├── AppIcon.appiconset/
│   │   │   │   │   └── Contents.json
│   │   │   │   └── Contents.json
│   │   │   ├── Info.plist
│   │   │   ├── LaunchScreen.storyboard
│   │   │   └── main.m
│   │   ├── RtmpExample-Bridging-Header.h
│   │   ├── RtmpExample.xcodeproj/
│   │   │   ├── project.pbxproj
│   │   │   └── xcshareddata/
│   │   │       └── xcschemes/
│   │   │           └── RtmpExample.xcscheme
│   │   ├── RtmpExample.xcworkspace/
│   │   │   ├── contents.xcworkspacedata
│   │   │   └── xcshareddata/
│   │   │       └── IDEWorkspaceChecks.plist
│   │   ├── assets/
│   │   │   └── app.json
│   │   └── main.jsbundle
│   ├── metro.config.js
│   ├── package.json
│   └── src/
│       ├── App.styles.tsx
│       ├── App.tsx
│       ├── components/
│       │   ├── Button/
│       │   │   ├── Button.styles.tsx
│       │   │   ├── Button.tsx
│       │   │   └── index.ts
│       │   ├── LiveBadge/
│       │   │   ├── LiveBadge.styles.tsx
│       │   │   ├── LiveBadge.tsx
│       │   │   └── index.ts
│       │   └── MicrophoneSelectModal/
│       │       ├── MicrophoneSelectModal.styles.tsx
│       │       ├── MicrophoneSelectModal.tsx
│       │       └── index.ts
│       └── hooks/
│           └── usePermissions.ts
├── ios/
│   ├── Podfile
│   ├── RTMPCreator.swift
│   ├── RTMPManager/
│   │   ├── RTMPView.swift
│   │   ├── RTMPViewManager.m
│   │   └── RTMPViewManager.swift
│   ├── RTMPModule/
│   │   ├── RTMPModule.m
│   │   └── RTMPModule.swift
│   ├── RtmpPublish-Bridging-Header.h
│   ├── RtmpPublish.xcodeproj/
│   │   └── project.pbxproj
│   └── RtmpPublish.xcworkspace/
│       ├── contents.xcworkspacedata
│       └── xcshareddata/
│           └── IDEWorkspaceChecks.plist
├── jest.config.js
├── package.json
├── react-native-rtmp-publisher.podspec
├── scripts/
│   └── bootstrap.js
├── src/
│   ├── Component.tsx
│   ├── RTMPPublisher.tsx
│   ├── index.tsx
│   ├── test/
│   │   ├── RTMPPublisher.test.tsx
│   │   └── __snapshots__/
│   │       └── RTMPPublisher.test.tsx.snap
│   └── types.ts
├── tsconfig.build.json
└── tsconfig.json
Download .txt
SYMBOL INDEX (177 symbols across 35 files)

FILE: android/src/main/java/com/reactnativertmppublisher/RTMPManager.java
  class RTMPManager (line 19) | public class RTMPManager extends SimpleViewManager<SurfaceView> {
    method onLayoutChange (line 27) | @Override
    method getName (line 33) | @NonNull
    method createViewInstance (line 39) | @NonNull
    method setStreamURL (line 53) | @ReactProp(name = "streamURL")
    method setStreamName (line 58) | @ReactProp(name = "streamName")
    method getExportedCustomDirectEventTypeConstants (line 63) | @Nullable

FILE: android/src/main/java/com/reactnativertmppublisher/RTMPModule.java
  class RTMPModule (line 12) | public class RTMPModule extends ReactContextBaseJavaModule {
    method RTMPModule (line 15) | public RTMPModule(@Nullable ReactApplicationContext reactContext) {
    method getName (line 19) | @NonNull
    method isStreaming (line 25) | @ReactMethod
    method isCameraOnPreview (line 35) | @ReactMethod
    method getPublishURL (line 45) | @ReactMethod
    method hasCongestion (line 55) | @ReactMethod
    method isAudioPrepared (line 65) | @ReactMethod
    method isVideoPrepared (line 75) | @ReactMethod
    method isMuted (line 85) | @ReactMethod
    method mute (line 95) | @ReactMethod
    method unmute (line 108) | @ReactMethod
    method switchCamera (line 121) | @ReactMethod
    method startStream (line 130) | @ReactMethod
    method stopStream (line 139) | @ReactMethod
    method toggleFlash (line 148) | @ReactMethod
    method setAudioInput (line 157) | @ReactMethod

FILE: android/src/main/java/com/reactnativertmppublisher/RTMPPackage.java
  class RTMPPackage (line 14) | public class RTMPPackage implements ReactPackage {
    method createNativeModules (line 15) | @NonNull
    method createViewManagers (line 23) | @NonNull

FILE: android/src/main/java/com/reactnativertmppublisher/enums/AudioInputType.java
  type AudioInputType (line 3) | public enum AudioInputType {

FILE: android/src/main/java/com/reactnativertmppublisher/enums/BluetoothDeviceStatuses.java
  type BluetoothDeviceStatuses (line 3) | public enum BluetoothDeviceStatuses {

FILE: android/src/main/java/com/reactnativertmppublisher/enums/StreamState.java
  type StreamState (line 3) | public enum StreamState {

FILE: android/src/main/java/com/reactnativertmppublisher/interfaces/ConnectionListener.java
  type ConnectionListener (line 5) | public interface ConnectionListener {
    method onChange (line 6) | void onChange(String type, @Nullable Object data);

FILE: android/src/main/java/com/reactnativertmppublisher/modules/BluetoothDeviceConnector.java
  class BluetoothDeviceConnector (line 17) | public class BluetoothDeviceConnector extends BroadcastReceiver implemen...
    method addListener (line 20) | public void addListener(ConnectionListener listener) {
    method BluetoothDeviceConnector (line 24) | public BluetoothDeviceConnector(Context context) {
    method onServiceConnected (line 30) | @Override
    method onServiceDisconnected (line 39) | @Override
    method onReceive (line 46) | @Override

FILE: android/src/main/java/com/reactnativertmppublisher/modules/ConnectionChecker.java
  class ConnectionChecker (line 11) | public class ConnectionChecker implements ConnectCheckerRtmp {
    method addListener (line 14) | public void addListener(ConnectionListener listener) {
    method onAuthErrorRtmp (line 18) | @Override
    method onAuthSuccessRtmp (line 25) | @Override
    method onConnectionFailedRtmp (line 33) | @Override
    method onConnectionStartedRtmp (line 41) | @Override
    method onConnectionSuccessRtmp (line 48) | @Override
    method onDisconnectRtmp (line 55) | @Override
    method onNewBitrateRtmp (line 63) | @Override

FILE: android/src/main/java/com/reactnativertmppublisher/modules/Publisher.java
  class Publisher (line 21) | public class Publisher {
    method Publisher (line 31) | public Publisher(ThemedReactContext reactContext, SurfaceView surfaceV...
    method getRtmpCamera (line 44) | public RtmpCamera1 getRtmpCamera() {
    method createConnectionListener (line 48) | public ConnectionListener createConnectionListener() {
    method createBluetoothDeviceListener (line 59) | public ConnectionListener createBluetoothDeviceListener(){
    method eventEffect (line 70) | private void eventEffect(@NonNull String eventType) {
    method getPublishURL (line 116) | public String getPublishURL() {
    method setStreamUrl (line 120) | public void setStreamUrl(String _streamUrl) {
    method setStreamName (line 124) | public void setStreamName(String _streamName) {
    method isStreaming (line 128) | public boolean isStreaming() {
    method isOnPreview (line 132) | public boolean isOnPreview() {
    method isAudioPrepared (line 136) | public boolean isAudioPrepared() {
    method isVideoPrepared (line 140) | public boolean isVideoPrepared() {
    method hasCongestion (line 144) | public boolean hasCongestion() {
    method isAudioMuted (line 148) | public boolean isAudioMuted() {
    method disableAudio (line 152) | public void disableAudio() {
    method enableAudio (line 156) | public void enableAudio() {
    method switchCamera (line 160) | public void switchCamera() {
    method toggleFlash (line 164) | public void toggleFlash() {
    method startStream (line 178) | public void startStream() {
    method stopStream (line 194) | public void stopStream() {
    method setAudioInput (line 208) | public void setAudioInput(@NonNull AudioInputType audioInputType){

FILE: android/src/main/java/com/reactnativertmppublisher/modules/SurfaceHolderHelper.java
  class SurfaceHolderHelper (line 11) | public class SurfaceHolderHelper implements SurfaceHolder.Callback {
    method SurfaceHolderHelper (line 14) | public SurfaceHolderHelper(ThemedReactContext reactContext, RtmpCamera...
    method surfaceCreated (line 18) | @Override
    method surfaceChanged (line 23) | @Override
    method surfaceDestroyed (line 28) | @Override

FILE: android/src/main/java/com/reactnativertmppublisher/utils/ObjectCaster.java
  class ObjectCaster (line 8) | public class ObjectCaster {
    method caster (line 9) | public static WritableMap caster(@Nullable Object data){

FILE: coverage/lcov-report/block-navigation.js
  function toggleClass (line 24) | function toggleClass(index) {
  function makeCurrent (line 31) | function makeCurrent(index) {
  function goToPrevious (line 41) | function goToPrevious() {
  function goToNext (line 52) | function goToNext() {

FILE: coverage/lcov-report/prettify.js
  function k (line 2) | function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V...
  function a (line 2) | function a(V){var U=/(?:^|\s)nocode(?:\s|$)/;var X=[];var T=0;var Z=[];v...
  function B (line 2) | function B(S,U,W,T){if(!U){return}var V={sourceCode:U,basePos:S};W(V);T....
  function o (line 2) | function o(S){var V=undefined;for(var U=S.firstChild;U;U=U.nextSibling){...
  function g (line 2) | function g(U,T){var S={};var V;(function(){var ad=U.concat(T);var ah=[];...
  function i (line 2) | function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\...
  function Q (line 2) | function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac...
  function D (line 2) | function D(ac){var aj=/\bMSIE\b/.test(navigator.userAgent);var am=/\n/g;...
  function c (line 2) | function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnPrope...
  function q (line 2) | function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*</.test(S)?"default...
  function d (line 2) | function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.so...
  function y (line 2) | function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U...
  function b (line 2) | function b(ad){function Y(af){return document.getElementsByTagName(af)}v...

FILE: coverage/lcov-report/sorter.js
  function getTable (line 11) | function getTable() {
  function getTableHeader (line 15) | function getTableHeader() {
  function getTableBody (line 19) | function getTableBody() {
  function getNthColumn (line 23) | function getNthColumn(n) {
  function onFilterInput (line 27) | function onFilterInput() {
  function addSearchBox (line 45) | function addSearchBox() {
  function loadColumns (line 53) | function loadColumns() {
  function loadRowData (line 78) | function loadRowData(tableRow) {
  function loadData (line 97) | function loadData() {
  function sortByIndex (line 106) | function sortByIndex(index, desc) {
  function removeSortIndicators (line 137) | function removeSortIndicators() {
  function addSortIndicators (line 145) | function addSortIndicators() {
  function enableUI (line 151) | function enableUI() {

FILE: example/android/app/src/debug/java/com/example/reactnativertmp/ReactNativeFlipper.java
  class ReactNativeFlipper (line 28) | public class ReactNativeFlipper {
    method initializeFlipper (line 29) | public static void initializeFlipper(Context context, ReactInstanceMan...

FILE: example/android/app/src/main/java/com/example/reactnativertmp/MainActivity.java
  class MainActivity (line 7) | public class MainActivity extends ReactActivity {
    method getMainComponentName (line 13) | @Override
    method createReactActivityDelegate (line 23) | @Override
    class MainActivityDelegate (line 27) | public static class MainActivityDelegate extends ReactActivityDelegate {
      method MainActivityDelegate (line 28) | public MainActivityDelegate(ReactActivity activity, String mainCompo...
      method createRootView (line 31) | @Override
      method isConcurrentRootEnabled (line 38) | @Override

FILE: example/android/app/src/main/java/com/example/reactnativertmp/MainApplication.java
  class MainApplication (line 17) | public class MainApplication extends Application implements ReactApplica...
    method getUseDeveloperSupport (line 21) | @Override
    method getPackages (line 26) | @Override
    method getJSMainModuleName (line 36) | @Override
    method getReactNativeHost (line 45) | @Override
    method onCreate (line 54) | @Override
    method initializeFlipper (line 68) | private static void initializeFlipper(Context context, ReactInstanceMa...

FILE: example/android/app/src/main/java/com/example/reactnativertmp/newarchitecture/MainApplicationReactNativeHost.java
  class MainApplicationReactNativeHost (line 35) | public class MainApplicationReactNativeHost extends ReactNativeHost {
    method MainApplicationReactNativeHost (line 36) | public MainApplicationReactNativeHost(Application application) {
    method getUseDeveloperSupport (line 40) | @Override
    method getPackages (line 45) | @Override
    method getJSMainModuleName (line 57) | @Override
    method getReactPackageTurboModuleManagerDelegateBuilder (line 62) | @NonNull
    method getJSIModulePackage (line 71) | @Override

FILE: example/android/app/src/main/java/com/example/reactnativertmp/newarchitecture/components/MainComponentsRegistry.java
  class MainComponentsRegistry (line 16) | @DoNotStrip
    method initHybrid (line 24) | @DoNotStrip
    method MainComponentsRegistry (line 27) | @DoNotStrip
    method register (line 32) | @DoNotStrip

FILE: example/android/app/src/main/java/com/example/reactnativertmp/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java
  class MainApplicationTurboModuleManagerDelegate (line 18) | public class MainApplicationTurboModuleManagerDelegate
    method MainApplicationTurboModuleManagerDelegate (line 23) | protected MainApplicationTurboModuleManagerDelegate(
    method initHybrid (line 28) | protected native HybridData initHybrid();
    method canCreateTurboModule (line 30) | native boolean canCreateTurboModule(String moduleName);
    class Builder (line 32) | public static class Builder extends ReactPackageTurboModuleManagerDele...
      method build (line 33) | protected MainApplicationTurboModuleManagerDelegate build(
    method maybeLoadOtherSoLibraries (line 39) | @Override

FILE: example/android/app/src/main/jni/MainApplicationModuleProvider.cpp
  type facebook (line 6) | namespace facebook {
    type react (line 7) | namespace react {
      function MainApplicationModuleProvider (line 9) | std::shared_ptr<TurboModule> MainApplicationModuleProvider(

FILE: example/android/app/src/main/jni/MainApplicationModuleProvider.h
  function namespace (line 8) | namespace facebook {

FILE: example/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp
  type facebook (line 4) | namespace facebook {
    type react (line 5) | namespace react {

FILE: example/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h
  function namespace (line 7) | namespace facebook {

FILE: example/android/app/src/main/jni/MainComponentsRegistry.cpp
  type facebook (line 9) | namespace facebook {
    type react (line 10) | namespace react {

FILE: example/android/app/src/main/jni/MainComponentsRegistry.h
  function namespace (line 8) | namespace facebook {

FILE: example/android/app/src/main/jni/OnLoad.cpp
  function JNIEXPORT (line 5) | JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {

FILE: example/src/App.tsx
  constant STREAM_URL (line 18) | const STREAM_URL = 'YOUR_STREAM_URL';
  constant STREAM_NAME (line 19) | const STREAM_NAME = 'YOUR_STREAM_NAME';
  function App (line 21) | function App() {

FILE: example/src/components/Button/Button.tsx
  type ButtonType (line 6) | type ButtonType = 'default' | 'circle';
  type ButtonProps (line 8) | interface ButtonProps {

FILE: example/src/components/MicrophoneSelectModal/MicrophoneSelectModal.tsx
  type ButtonProps (line 8) | interface ButtonProps {

FILE: example/src/hooks/usePermissions.ts
  constant CAMERA_PERMISSION (line 4) | const CAMERA_PERMISSION = PermissionsAndroid.PERMISSIONS.CAMERA;
  constant AUDIO_PERMISSION (line 5) | const AUDIO_PERMISSION = PermissionsAndroid.PERMISSIONS.RECORD_AUDIO;
  constant BLUETOOTH_PERMISSION (line 6) | const BLUETOOTH_PERMISSION = PermissionsAndroid.PERMISSIONS.BLUETOOTH_CO...
  function usePermissions (line 8) | function usePermissions() {

FILE: src/Component.tsx
  type RTMPData (line 8) | type RTMPData<T> = { data: T };
  type ConnectionFailedType (line 10) | type ConnectionFailedType = NativeSyntheticEvent<RTMPData<string>>;
  type ConnectionStartedType (line 11) | type ConnectionStartedType = NativeSyntheticEvent<RTMPData<string>>;
  type ConnectionSuccessType (line 12) | type ConnectionSuccessType = NativeSyntheticEvent<RTMPData<null>>;
  type DisconnectType (line 13) | type DisconnectType = NativeSyntheticEvent<RTMPData<null>>;
  type NewBitrateReceivedType (line 14) | type NewBitrateReceivedType = NativeSyntheticEvent<RTMPData<number>>;
  type StreamStateChangedType (line 15) | type StreamStateChangedType = NativeSyntheticEvent<
  type BluetoothDeviceStatusChangedType (line 18) | type BluetoothDeviceStatusChangedType = NativeSyntheticEvent<
  type NativeRTMPPublisherProps (line 21) | interface NativeRTMPPublisherProps {

FILE: src/RTMPPublisher.tsx
  type RTMPPublisherProps (line 20) | interface RTMPPublisherProps {

FILE: src/types.ts
  type RTMPPublisherRefProps (line 3) | interface RTMPPublisherRefProps {
  type RTMPPublisherProps (line 62) | interface RTMPPublisherProps {
  type StreamStatus (line 73) | type StreamStatus =
  type StreamState (line 79) | enum StreamState {
  type BluetoothDeviceStatuses (line 85) | enum BluetoothDeviceStatuses {
  type AudioInputType (line 91) | enum AudioInputType {
Condensed preview — 132 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,066K chars).
[
  {
    "path": ".editorconfig",
    "chars": 283,
    "preview": "# EditorConfig helps developers define and maintain consistent\n# coding styles between different editors and IDEs\n# edit"
  },
  {
    "path": ".gitattributes",
    "chars": 71,
    "preview": "*.pbxproj -text\n# specific for windows script files\n*.bat text eol=crlf"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.yml",
    "chars": 1694,
    "preview": "name: Bug Report\ndescription: File a bug report\nbody:\n  - type: textarea\n    id: describe-the-bug\n    attributes:\n      "
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "chars": 595,
    "preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Is your fea"
  },
  {
    "path": ".github/workflows/build.yml",
    "chars": 3077,
    "preview": "name: Build\n\non:\n  pull_request:\n    branches:\n      - master\n      - dev\n\njobs:\n  build_dependency:\n    runs-on: ubuntu"
  },
  {
    "path": ".gitignore",
    "chars": 643,
    "preview": "# OSX\n#\n.DS_Store\n\n# XDE\n.expo/\n\n# VSCode\n.vscode/\njsconfig.json\n\n# Xcode\n#\nbuild/\n*.pbxuser\n!default.pbxuser\n*.mode1v3\n"
  },
  {
    "path": ".husky/.npmignore",
    "chars": 2,
    "preview": "_\n"
  },
  {
    "path": ".husky/commit-msg",
    "chars": 78,
    "preview": "#!/bin/sh\n. \"$(dirname \"$0\")/_/husky.sh\"\n\nyarn commitlint -E HUSKY_GIT_PARAMS\n"
  },
  {
    "path": ".husky/pre-commit",
    "chars": 71,
    "preview": "#!/bin/sh\n. \"$(dirname \"$0\")/_/husky.sh\"\n\nyarn lint && yarn typescript\n"
  },
  {
    "path": ".yarnrc",
    "chars": 115,
    "preview": "# Override Yarn command so we can automatically setup the repo on running `yarn`\n\nyarn-path \"scripts/bootstrap.js\"\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 5202,
    "preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participa"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 9233,
    "preview": "# Contributing\n\nWe want this community to be friendly and respectful to each other. Please follow it in all your interac"
  },
  {
    "path": "LICENSE",
    "chars": 1062,
    "preview": "MIT License\n\nCopyright (c) 2021 Ezran\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof t"
  },
  {
    "path": "README.md",
    "chars": 9436,
    "preview": "### ⚠️⚠️⚠️ THIS PACKAGE CURRENTLY UNMAINTENED. WILL RE-MAINTENED IN SOON WITH NEW ARCH ⚠️⚠️⚠️\n\n<p align=\"center\">\n<img s"
  },
  {
    "path": "__mocks__/RTMPPublisher.js",
    "chars": 422,
    "preview": "import { NativeModules } from 'react-native';\n\nNativeModules.RTMPPublisher = {\n  startStream: jest.fn(),\n  stopStream: j"
  },
  {
    "path": "android/build.gradle",
    "chars": 1387,
    "preview": "buildscript {\n  if (project == rootProject) {\n    repositories {\n      google()\n      mavenCentral()\n      jcenter()\n   "
  },
  {
    "path": "android/gradle/wrapper/gradle-wrapper.properties",
    "chars": 200,
    "preview": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributi"
  },
  {
    "path": "android/gradlew",
    "chars": 5766,
    "preview": "#!/usr/bin/env sh\n\n#\n# Copyright 2015 the original author or authors.\n#\n# Licensed under the Apache License, Version 2.0"
  },
  {
    "path": "android/gradlew.bat",
    "chars": 2763,
    "preview": "@rem\r\n@rem Copyright 2015 the original author or authors.\r\n@rem\r\n@rem Licensed under the Apache License, Version 2.0 (th"
  },
  {
    "path": "android/src/main/AndroidManifest.xml",
    "chars": 200,
    "preview": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n          package=\"com.reactnativertmppublisher\">\n\n"
  },
  {
    "path": "android/src/main/java/com/reactnativertmppublisher/RTMPManager.java",
    "chars": 2987,
    "preview": "package com.reactnativertmppublisher;\n\nimport android.view.SurfaceView;\nimport android.view.View;\n\nimport androidx.annot"
  },
  {
    "path": "android/src/main/java/com/reactnativertmppublisher/RTMPModule.java",
    "chars": 3819,
    "preview": "package com.reactnativertmppublisher;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport "
  },
  {
    "path": "android/src/main/java/com/reactnativertmppublisher/RTMPPackage.java",
    "chars": 843,
    "preview": "package com.reactnativertmppublisher;\n\nimport androidx.annotation.NonNull;\n\nimport com.facebook.react.ReactPackage;\nimpo"
  },
  {
    "path": "android/src/main/java/com/reactnativertmppublisher/enums/AudioInputType.java",
    "chars": 107,
    "preview": "package com.reactnativertmppublisher.enums;\n\npublic enum AudioInputType {\n  BLUETOOTH_HEADSET,\n  SPEAKER\n}\n"
  },
  {
    "path": "android/src/main/java/com/reactnativertmppublisher/enums/BluetoothDeviceStatuses.java",
    "chars": 127,
    "preview": "package com.reactnativertmppublisher.enums;\n\npublic enum BluetoothDeviceStatuses {\n  CONNECTING,\n  CONNECTED,\n  DISCONNE"
  },
  {
    "path": "android/src/main/java/com/reactnativertmppublisher/enums/StreamState.java",
    "chars": 125,
    "preview": "package com.reactnativertmppublisher.enums;\n\npublic enum StreamState {\n  CONNECTING,\n  CONNECTED,\n  DISCONNECTED,\n  FAIL"
  },
  {
    "path": "android/src/main/java/com/reactnativertmppublisher/interfaces/ConnectionListener.java",
    "chars": 183,
    "preview": "package com.reactnativertmppublisher.interfaces;\n\nimport androidx.annotation.Nullable;\n\npublic interface ConnectionListe"
  },
  {
    "path": "android/src/main/java/com/reactnativertmppublisher/modules/BluetoothDeviceConnector.java",
    "chars": 2507,
    "preview": "package com.reactnativertmppublisher.modules;\n\nimport android.bluetooth.BluetoothAdapter;\nimport android.bluetooth.Bluet"
  },
  {
    "path": "android/src/main/java/com/reactnativertmppublisher/modules/ConnectionChecker.java",
    "chars": 1755,
    "preview": "package com.reactnativertmppublisher.modules;\n\nimport androidx.annotation.NonNull;\n\nimport com.pedro.rtmp.utils.ConnectC"
  },
  {
    "path": "android/src/main/java/com/reactnativertmppublisher/modules/Publisher.java",
    "chars": 6621,
    "preview": "package com.reactnativertmppublisher.modules;\n\nimport android.content.Context;\nimport android.media.AudioManager;\nimport"
  },
  {
    "path": "android/src/main/java/com/reactnativertmppublisher/modules/SurfaceHolderHelper.java",
    "chars": 838,
    "preview": "package com.reactnativertmppublisher.modules;\n\n\nimport android.view.SurfaceHolder;\n\nimport androidx.annotation.NonNull;\n"
  },
  {
    "path": "android/src/main/java/com/reactnativertmppublisher/utils/ObjectCaster.java",
    "chars": 729,
    "preview": "package com.reactnativertmppublisher.utils;\n\nimport androidx.annotation.Nullable;\n\nimport com.facebook.react.bridge.Argu"
  },
  {
    "path": "babel.config.js",
    "chars": 77,
    "preview": "module.exports = {\n  presets: ['module:metro-react-native-babel-preset'],\n};\n"
  },
  {
    "path": "coverage/clover.xml",
    "chars": 396,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<coverage generated=\"1674417315429\" clover=\"3.2.0\">\n  <project timestamp=\"1674417"
  },
  {
    "path": "coverage/coverage-final.json",
    "chars": 3,
    "preview": "{}\n"
  },
  {
    "path": "coverage/lcov-report/Component.tsx.html",
    "chars": 7977,
    "preview": "\n<!doctype html>\n<html lang=\"en\">\n\n<head>\n    <title>Code coverage report for Component.tsx</title>\n    <meta charset=\"u"
  },
  {
    "path": "coverage/lcov-report/RTMPPublisher.tsx.html",
    "chars": 24726,
    "preview": "\n<!doctype html>\n<html lang=\"en\">\n\n<head>\n    <title>Code coverage report for RTMPPublisher.tsx</title>\n    <meta charse"
  },
  {
    "path": "coverage/lcov-report/base.css",
    "chars": 5394,
    "preview": "body, html {\n  margin:0; padding: 0;\n  height: 100%;\n}\nbody {\n    font-family: Helvetica Neue, Helvetica, Arial;\n    fon"
  },
  {
    "path": "coverage/lcov-report/block-navigation.js",
    "chars": 2655,
    "preview": "/* eslint-disable */\nvar jumpToCode = (function init() {\n    // Classes of code we would like to highlight in the file v"
  },
  {
    "path": "coverage/lcov-report/index.html",
    "chars": 3744,
    "preview": "\n<!doctype html>\n<html lang=\"en\">\n\n<head>\n    <title>Code coverage report for All files</title>\n    <meta charset=\"utf-8"
  },
  {
    "path": "coverage/lcov-report/prettify.css",
    "chars": 676,
    "preview": ".pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,"
  },
  {
    "path": "coverage/lcov-report/prettify.js",
    "chars": 17590,
    "preview": "/* eslint-disable */\nwindow.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=[\"break,continue,do,else,for,if,return,whi"
  },
  {
    "path": "coverage/lcov-report/sorter.js",
    "chars": 6181,
    "preview": "/* eslint-disable */\nvar addSorting = (function() {\n    'use strict';\n    var cols,\n        currentSort = {\n            "
  },
  {
    "path": "coverage/lcov.info",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "example/README.md",
    "chars": 611,
    "preview": "# Example Project\n\nClone the repo and run\n\n```sh\nyarn\n```\nand\n\n```sh\ncd example && yarn ios (or yarn android)\n```\nYou ca"
  },
  {
    "path": "example/android/app/build.gradle",
    "chars": 12842,
    "preview": "apply plugin: \"com.android.application\"\n\nimport com.android.build.OutputFile\nimport org.apache.tools.ant.taskdefs.condit"
  },
  {
    "path": "example/android/app/proguard-rules.pro",
    "chars": 435,
    "preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /u"
  },
  {
    "path": "example/android/app/src/debug/AndroidManifest.xml",
    "chars": 519,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:to"
  },
  {
    "path": "example/android/app/src/debug/java/com/example/reactnativertmp/ReactNativeFlipper.java",
    "chars": 3308,
    "preview": "/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * <p>This source code is licensed under the MIT license foun"
  },
  {
    "path": "example/android/app/src/main/AndroidManifest.xml",
    "chars": 1219,
    "preview": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  package=\"com.example.reactnativertmp\">\n\n  <uses-p"
  },
  {
    "path": "example/android/app/src/main/java/com/example/reactnativertmp/MainActivity.java",
    "chars": 1648,
    "preview": "package com.example.reactnativertmp;\n\nimport com.facebook.react.ReactActivity;\nimport com.facebook.react.ReactActivityDe"
  },
  {
    "path": "example/android/app/src/main/java/com/example/reactnativertmp/MainApplication.java",
    "chars": 3129,
    "preview": "package com.example.reactnativertmp;\n\nimport android.app.Application;\nimport android.content.Context;\nimport com.faceboo"
  },
  {
    "path": "example/android/app/src/main/java/com/example/reactnativertmp/newarchitecture/MainApplicationReactNativeHost.java",
    "chars": 4674,
    "preview": "package com.example.reactnativertmp.newarchitecture;\n\nimport android.app.Application;\nimport androidx.annotation.NonNull"
  },
  {
    "path": "example/android/app/src/main/java/com/example/reactnativertmp/newarchitecture/components/MainComponentsRegistry.java",
    "chars": 1170,
    "preview": "package com.example.reactnativertmp.newarchitecture.components;\n\nimport com.facebook.jni.HybridData;\nimport com.facebook"
  },
  {
    "path": "example/android/app/src/main/java/com/example/reactnativertmp/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java",
    "chars": 1807,
    "preview": "package com.example.reactnativertmp.newarchitecture.modules;\n\nimport com.facebook.jni.HybridData;\nimport com.facebook.re"
  },
  {
    "path": "example/android/app/src/main/jni/CMakeLists.txt",
    "chars": 279,
    "preview": "cmake_minimum_required(VERSION 3.13)\n\n# Define the library name here.\nproject(reactnativertmp_appmodules)\n\n# This file i"
  },
  {
    "path": "example/android/app/src/main/jni/MainApplicationModuleProvider.cpp",
    "chars": 960,
    "preview": "#include \"MainApplicationModuleProvider.h\"\n\n#include <rncli.h>\n#include <rncore.h>\n\nnamespace facebook {\nnamespace react"
  },
  {
    "path": "example/android/app/src/main/jni/MainApplicationModuleProvider.h",
    "chars": 322,
    "preview": "#pragma once\n\n#include <memory>\n#include <string>\n\n#include <ReactCommon/JavaTurboModule.h>\n\nnamespace facebook {\nnamesp"
  },
  {
    "path": "example/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp",
    "chars": 1407,
    "preview": "#include \"MainApplicationTurboModuleManagerDelegate.h\"\n#include \"MainApplicationModuleProvider.h\"\n\nnamespace facebook {\n"
  },
  {
    "path": "example/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h",
    "chars": 1167,
    "preview": "#include <memory>\n#include <string>\n\n#include <ReactCommon/TurboModuleManagerDelegate.h>\n#include <fbjni/fbjni.h>\n\nnames"
  },
  {
    "path": "example/android/app/src/main/jni/MainComponentsRegistry.cpp",
    "chars": 2164,
    "preview": "#include \"MainComponentsRegistry.h\"\n\n#include <CoreComponentsRegistry.h>\n#include <fbjni/fbjni.h>\n#include <react/render"
  },
  {
    "path": "example/android/app/src/main/jni/MainComponentsRegistry.h",
    "chars": 920,
    "preview": "#pragma once\n\n#include <ComponentFactory.h>\n#include <fbjni/fbjni.h>\n#include <react/renderer/componentregistry/Componen"
  },
  {
    "path": "example/android/app/src/main/jni/OnLoad.cpp",
    "chars": 381,
    "preview": "#include <fbjni/fbjni.h>\n#include \"MainApplicationTurboModuleManagerDelegate.h\"\n#include \"MainComponentsRegistry.h\"\n\nJNI"
  },
  {
    "path": "example/android/app/src/main/res/drawable/rn_edit_text_material.xml",
    "chars": 1910,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2014 The Android Open Source Project\n\n     Licensed under the "
  },
  {
    "path": "example/android/app/src/main/res/values/strings.xml",
    "chars": 75,
    "preview": "<resources>\n    <string name=\"app_name\">Rtmp Example</string>\n</resources>\n"
  },
  {
    "path": "example/android/app/src/main/res/values/styles.xml",
    "chars": 282,
    "preview": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.DayNight.NoActionBa"
  },
  {
    "path": "example/android/build.gradle",
    "chars": 1752,
    "preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n    e"
  },
  {
    "path": "example/android/gradle/wrapper/gradle-wrapper.properties",
    "chars": 202,
    "preview": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributi"
  },
  {
    "path": "example/android/gradle.properties",
    "chars": 1422,
    "preview": "# Project-wide Gradle settings.\n\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will o"
  },
  {
    "path": "example/android/gradlew",
    "chars": 8046,
    "preview": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"Lice"
  },
  {
    "path": "example/android/gradlew.bat",
    "chars": 2761,
    "preview": "@rem\r\n@rem Copyright 2015 the original author or authors.\r\n@rem\r\n@rem Licensed under the Apache License, Version 2.0 (th"
  },
  {
    "path": "example/android/settings.gradle",
    "chars": 741,
    "preview": "rootProject.name = 'RtmpExample'\napply from: file(\"../node_modules/@react-native-community/cli-platform-android/native_m"
  },
  {
    "path": "example/app.json",
    "chars": 61,
    "preview": "{\n  \"name\": \"RtmpExample\",\n  \"displayName\": \"Rtmp Example\"\n}\n"
  },
  {
    "path": "example/babel.config.js",
    "chars": 364,
    "preview": "const path = require('path');\nconst pak = require('../package.json');\n\nmodule.exports = {\n  presets: ['module:metro-reac"
  },
  {
    "path": "example/index.tsx",
    "chars": 171,
    "preview": "import { AppRegistry } from 'react-native';\nimport App from './src/App';\nimport { name as appName } from './app.json';\n\n"
  },
  {
    "path": "example/ios/.xcode.env",
    "chars": 480,
    "preview": "# This `.xcode.env` file is versioned and is used to source the environment\n# used when running script phases inside Xco"
  },
  {
    "path": "example/ios/File.swift",
    "chars": 56,
    "preview": "//\n//  File.swift\n//  RtmpExample\n//\n\nimport Foundation\n"
  },
  {
    "path": "example/ios/Podfile",
    "chars": 1898,
    "preview": "require_relative '../node_modules/react-native/scripts/react_native_pods'\nrequire_relative '../node_modules/@react-nativ"
  },
  {
    "path": "example/ios/RtmpExample/AppDelegate.h",
    "chars": 386,
    "preview": "/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found i"
  },
  {
    "path": "example/ios/RtmpExample/AppDelegate.mm",
    "chars": 5558,
    "preview": "#import \"AppDelegate.h\"\n\n#import <React/RCTBridge.h>\n#import <React/RCTBundleURLProvider.h>\n#import <React/RCTRootView.h"
  },
  {
    "path": "example/ios/RtmpExample/Images.xcassets/AppIcon.appiconset/Contents.json",
    "chars": 818,
    "preview": "{\n  \"images\": [\n    {\n      \"idiom\": \"iphone\",\n      \"scale\": \"2x\",\n      \"size\": \"20x20\"\n    },\n    {\n      \"idiom\": \"i"
  },
  {
    "path": "example/ios/RtmpExample/Images.xcassets/Contents.json",
    "chars": 63,
    "preview": "{\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}\n"
  },
  {
    "path": "example/ios/RtmpExample/Info.plist",
    "chars": 1708,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "example/ios/RtmpExample/LaunchScreen.storyboard",
    "chars": 4528,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3"
  },
  {
    "path": "example/ios/RtmpExample/main.m",
    "chars": 389,
    "preview": "/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found i"
  },
  {
    "path": "example/ios/RtmpExample-Bridging-Header.h",
    "chars": 103,
    "preview": "//\n//  Use this file to import your target's public headers that you would like to expose to Swift.\n//\n"
  },
  {
    "path": "example/ios/RtmpExample.xcodeproj/project.pbxproj",
    "chars": 24381,
    "preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
  },
  {
    "path": "example/ios/RtmpExample.xcodeproj/xcshareddata/xcschemes/RtmpExample.xcscheme",
    "chars": 3848,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"0940\"\n   version = \"1.3\">\n   <BuildAction\n      "
  },
  {
    "path": "example/ios/RtmpExample.xcworkspace/contents.xcworkspacedata",
    "chars": 229,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"group:RtmpExample.xc"
  },
  {
    "path": "example/ios/RtmpExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
    "chars": 238,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "example/ios/assets/app.json",
    "chars": 61,
    "preview": "{\n  \"name\": \"RtmpExample\",\n  \"displayName\": \"Rtmp Example\"\n}\n"
  },
  {
    "path": "example/ios/main.jsbundle",
    "chars": 741883,
    "preview": "var __BUNDLE_START_TIME__=this.nativePerformanceNow?nativePerformanceNow():Date.now(),__DEV__=false,process=this.process"
  },
  {
    "path": "example/metro.config.js",
    "chars": 1031,
    "preview": "const path = require('path');\nconst blacklist = require('metro-config/src/defaults/blacklist');\nconst escape = require('"
  },
  {
    "path": "example/package.json",
    "chars": 720,
    "preview": "{\n  \"name\": \"react-native-rtmp-publisher-example\",\n  \"description\": \"Example app for react-native-rtmp-publisher\",\n  \"ve"
  },
  {
    "path": "example/src/App.styles.tsx",
    "chars": 607,
    "preview": "import { StyleSheet } from 'react-native';\n\nexport default StyleSheet.create({\n  container: {\n    flex: 1,\n  },\n  publis"
  },
  {
    "path": "example/src/App.tsx",
    "chars": 4788,
    "preview": "import React, { useRef, useState } from 'react';\n\nimport { View, Platform } from 'react-native';\nimport RTMPPublisher, {"
  },
  {
    "path": "example/src/components/Button/Button.styles.tsx",
    "chars": 582,
    "preview": "import { StyleSheet } from 'react-native';\n\nexport default {\n  default: StyleSheet.create({\n    container: {\n      backg"
  },
  {
    "path": "example/src/components/Button/Button.tsx",
    "chars": 523,
    "preview": "import React from 'react';\nimport { TouchableOpacity, Text } from 'react-native';\n\nimport styles from './Button.styles';"
  },
  {
    "path": "example/src/components/Button/index.ts",
    "chars": 36,
    "preview": "export { default } from './Button';\n"
  },
  {
    "path": "example/src/components/LiveBadge/LiveBadge.styles.tsx",
    "chars": 504,
    "preview": "import { StyleSheet } from 'react-native';\n\nexport default StyleSheet.create({\n  container: {\n    backgroundColor: '#ece"
  },
  {
    "path": "example/src/components/LiveBadge/LiveBadge.tsx",
    "chars": 312,
    "preview": "import React from 'react';\nimport { View, Text } from 'react-native';\n\nimport styles from './LiveBadge.styles';\n\nconst L"
  },
  {
    "path": "example/src/components/LiveBadge/index.ts",
    "chars": 39,
    "preview": "export { default } from './LiveBadge';\n"
  },
  {
    "path": "example/src/components/MicrophoneSelectModal/MicrophoneSelectModal.styles.tsx",
    "chars": 657,
    "preview": "import { StyleSheet } from 'react-native';\n\nconst baseStyle = StyleSheet.create({\n  container: {\n    flex: 1,\n    justif"
  },
  {
    "path": "example/src/components/MicrophoneSelectModal/MicrophoneSelectModal.tsx",
    "chars": 2071,
    "preview": "import React, { useState } from 'react';\nimport { View, Text, Modal, TouchableOpacity, Platform } from 'react-native';\ni"
  },
  {
    "path": "example/src/components/MicrophoneSelectModal/index.ts",
    "chars": 51,
    "preview": "export { default } from './MicrophoneSelectModal';\n"
  },
  {
    "path": "example/src/hooks/usePermissions.ts",
    "chars": 1285,
    "preview": "import { useState, useEffect } from 'react';\nimport { PermissionsAndroid, Platform } from 'react-native';\n\nconst CAMERA_"
  },
  {
    "path": "ios/Podfile",
    "chars": 144,
    "preview": "source 'https://github.com/CocoaPods/Specs.git'\nuse_frameworks!\n\ntarget 'RtmpPublish' do\n  platform :ios, '10.0'\n\n  # Po"
  },
  {
    "path": "ios/RTMPCreator.swift",
    "chars": 3257,
    "preview": "//\n//  RTMPCreator.swift\n//  rtmpPackageExample\n//\n//  Created by Ezran Bayantemur on 15.01.2022.\n//\nimport HaishinKit\ni"
  },
  {
    "path": "ios/RTMPManager/RTMPView.swift",
    "chars": 3264,
    "preview": "//\n//  RTMPView.swift\n//  rtmpPackageExample\n//\n//  Created by Ezran Bayantemur on 15.01.2022.\n//\n\nimport UIKit\nimport H"
  },
  {
    "path": "ios/RTMPManager/RTMPViewManager.m",
    "chars": 755,
    "preview": "//\n//  RTMPViewManager.m\n//  rtmpPackageExample\n//\n//  Created by Ezran Bayantemur on 15.01.2022.\n//\n\n#import <React/RCT"
  },
  {
    "path": "ios/RTMPManager/RTMPViewManager.swift",
    "chars": 252,
    "preview": "//\n//  RTMPViewManager.swift\n//  rtmpPackageExample\n//\n//  Created by Ezran Bayantemur on 15.01.2022.\n//\n\nimport UIKit\n\n"
  },
  {
    "path": "ios/RTMPModule/RTMPModule.m",
    "chars": 2415,
    "preview": "//\n//  RTMPManager.m\n//  rtmpPackageExample\n//\n//  Created by Ezran Bayantemur on 15.01.2022.\n//\n\n#import <React/RCTBrid"
  },
  {
    "path": "ios/RTMPModule/RTMPModule.swift",
    "chars": 2351,
    "preview": "//\n//  RTMPManager.swift\n//  rtmpPackageExample\n//\n//  Created by Ezran Bayantemur on 15.01.2022.\n//\n\nimport AudioToolbo"
  },
  {
    "path": "ios/RtmpPublish-Bridging-Header.h",
    "chars": 205,
    "preview": "//\n//  Use this file to import your target's public headers that you would like to expose to Swift.\n//\n\n#import <React/R"
  },
  {
    "path": "ios/RtmpPublish.xcodeproj/project.pbxproj",
    "chars": 14813,
    "preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
  },
  {
    "path": "ios/RtmpPublish.xcworkspace/contents.xcworkspacedata",
    "chars": 229,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"group:RtmpPublish.xc"
  },
  {
    "path": "ios/RtmpPublish.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
    "chars": 238,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "jest.config.js",
    "chars": 96,
    "preview": "module.exports = {\n  preset: 'react-native',\n  setupFiles: ['./__mocks__/RTMPPublisher.js'],\n};\n"
  },
  {
    "path": "package.json",
    "chars": 3630,
    "preview": "{\n  \"name\": \"react-native-rtmp-publisher\",\n  \"version\": \"0.4.7\",\n  \"description\": \"RTM Publisher for React Native\",\n  \"m"
  },
  {
    "path": "react-native-rtmp-publisher.podspec",
    "chars": 634,
    "preview": "require \"json\"\n\npackage = JSON.parse(File.read(File.join(__dir__, \"package.json\")))\n\nPod::Spec.new do |s|\n  s.name      "
  },
  {
    "path": "scripts/bootstrap.js",
    "chars": 769,
    "preview": "const os = require('os');\nconst path = require('path');\nconst child_process = require('child_process');\n\nconst root = pa"
  },
  {
    "path": "src/Component.tsx",
    "chars": 1395,
    "preview": "import {\n  NativeSyntheticEvent,\n  requireNativeComponent,\n  ViewStyle,\n} from 'react-native';\nimport type { StreamState"
  },
  {
    "path": "src/RTMPPublisher.tsx",
    "chars": 4687,
    "preview": "import React, { forwardRef, useImperativeHandle } from 'react';\nimport { NativeModules, type ViewStyle } from 'react-nat"
  },
  {
    "path": "src/index.tsx",
    "chars": 193,
    "preview": "export { default } from './RTMPPublisher';\nexport {\n  RTMPPublisherProps,\n  RTMPPublisherRefProps,\n  StreamState,\n  Stre"
  },
  {
    "path": "src/test/RTMPPublisher.test.tsx",
    "chars": 3197,
    "preview": "import React from 'react';\nimport { fireEvent, render } from '@testing-library/react-native';\nimport RTMPPublisher, { RT"
  },
  {
    "path": "src/test/__snapshots__/RTMPPublisher.test.tsx.snap",
    "chars": 458,
    "preview": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`RTMPPublisher tests should match with snapshot 1`] = `\n<RTMPPublish"
  },
  {
    "path": "src/types.ts",
    "chars": 2015,
    "preview": "import type { ViewStyle } from 'react-native';\n\nexport interface RTMPPublisherRefProps {\n  /**\n   * Starts stream operat"
  },
  {
    "path": "tsconfig.build.json",
    "chars": 57,
    "preview": "\n{\n  \"extends\": \"./tsconfig\",\n  \"exclude\": [\"example\"]\n}\n"
  },
  {
    "path": "tsconfig.json",
    "chars": 708,
    "preview": "{\n  \"compilerOptions\": {\n    \"baseUrl\": \"./\",\n    \"paths\": {\n      \"react-native-rtmp-publisher\": [\"./src/index\"]\n    },"
  }
]

// ... and 3 more files (download for full content)

About this extraction

This page contains the full source code of the ezranbayantemur/react-native-rtmp-publisher GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 132 files (1010.5 KB), approximately 318.4k tokens, and a symbol index with 177 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!