v1 - blank slate

This commit is contained in:
rishikanthc
2025-08-19 19:12:40 -07:00
parent ef659a2248
commit 37b0ca8f9f
375 changed files with 0 additions and 40685 deletions

View File

@@ -1,63 +0,0 @@
# Use a specific version of Ubuntu as the base image
FROM ubuntu:24.04
# Set environment variables
ENV DEBIAN_FRONTEND=noninteractive \
TZ="Etc/UTC" \
PATH="/root/.local/bin/:$PATH"
# Install minimal runtime dependencies
RUN apt-get update && \
apt-get install -y \
python3 \
python3-pip \
python3-venv \
postgresql-client \
software-properties-common \
tzdata \
ffmpeg \
curl \
unzip \
git && \
# Add the PPA and install audiowaveform
add-apt-repository ppa:chris-needham/ppa && \
apt-get update && \
apt-get install -y audiowaveform && \
# Install UV
curl -sSL https://astral.sh/uv/install.sh -o /uv-installer.sh && \
sh /uv-installer.sh && \
rm /uv-installer.sh && \
# Install Node.js
curl -fsSL https://deb.nodesource.com/setup_23.x | bash - && \
apt-get install -y nodejs && \
# Clean up
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# Set working directory
WORKDIR /app
# Copy only the files needed for dependency installation and runtime
COPY . .
# Copy environment variables for initial build
# We use dynamic environment variables at runtime
# No .env file needed during build
# Install node dependencies and build frontend
RUN npm ci && \
npm install && \
npm run build
# Ensure entrypoint script is executable
RUN chmod +x docker-entrypoint.sh
# Expose port
EXPOSE 3000
# Remove environment variables file after build
# No need to remove .env as we don't create it
# Define default command
CMD ["./docker-entrypoint.sh"]

View File

@@ -1,62 +0,0 @@
FROM nvidia/cuda:12.8.0-cudnn-runtime-ubuntu24.04
# Set environment variables
ENV DEBIAN_FRONTEND=noninteractive \
TZ="Etc/UTC" \
PATH="/root/.local/bin/:$PATH"
# Install minimal runtime dependencies
RUN apt-get update && \
apt-get install -y \
python3 \
python3-pip \
python3-venv \
postgresql-client \
software-properties-common \
tzdata \
ffmpeg \
curl \
unzip \
git && \
# Add the PPA and install audiowaveform
add-apt-repository ppa:chris-needham/ppa && \
apt-get update && \
apt-get install -y audiowaveform && \
# Install UV
curl -sSL https://astral.sh/uv/install.sh -o /uv-installer.sh && \
sh /uv-installer.sh && \
rm /uv-installer.sh && \
# Install Node.js
curl -fsSL https://deb.nodesource.com/setup_23.x | bash - && \
apt-get install -y nodejs && \
# Clean up
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# Set working directory
WORKDIR /app
# Copy files to container
COPY . .
# Copy environment variables for initial build
# We use dynamic environment variables at runtime
# No .env file needed during build
# Install node dependencies and build frontend
RUN npm ci && \
npm install && \
npm run build
# Ensure entrypoint script is executable
RUN chmod +x docker-entrypoint.sh
# Expose port
EXPOSE 3000
# Remove environment variables file after build
# No need to remove .env as we don't create it
# Define default command
CMD ["./docker-entrypoint.sh"]

21
LICENSE
View File

@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2025 Rishikanth Chandrasekaran
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.

302
README.md
View File

@@ -1,302 +0,0 @@
# Scriberr - Self-hosted AI Transcription App
## About
Scriberr is a self-hostable AI audio transcription app. It leverages the open-source [Whisper](https://github.com/openai/whisper) models from OpenAI, utilizing the high-performance [WhisperX](https://github.com/m-bain/whisperX) transcription engine to transcribe audio files locally on your hardware. Scriberr also allows you to summarize transcripts using Ollama or OpenAI's ChatGPT API, with your own custom prompts. From v0.2.0, Scriberr supports offline speaker diarization with significant improvements.
**Note**: This app is under active development, and this release includes **breaking changes**. You will lose your old data. Please read the installation instructions carefully.
## Call for Beta Testers
Hi all, It's been several months since I started this project. The project has come a long way since then, and now, I'm about to release the first stable release v1.0.0. In light of this, I am releasing a beta version for seeking feedback before the release to smooth out any bugs. I request anyone interested to please try out the beta version and provide quality feedback so I can smooth any bugs out before the stable release.
## Updates
The stable version brings a lot of updates to the app. The app has been rebuilt from the ground up and also introduces a bunch of cool new features.
### Under the hood
The app has been rebuilt with Go for the backend and Svelte5 for the frontend and runs as a single binary file. The frontend is compiled to static website (plain HTML and JS) and this static website is embedded into the Go binary to provide a fast and highly responsive app. It uses Python for the actual AI transcription by leveraging the WhisperX engine for running Whisper models. This release is a breaking release and moves to using SQLite for the database. Audio files are stored to disk as is.
### New Features and improvements
* Fast transcription with support for all model sizes
* Automatic language detection
* Uses VAD and ASR models for better alignment and speech detection to remove silence periods
* Speaker diarization (Speaker detection and identification)
* Automatic summarization using OpenAI/Ollama endpoints
* Markdown rendering of Summaries (NEW)
* AI Chat with transcript using OpenAI/Ollama endpoints (NEW)
* Multiple chat sessions for each transcript (NEW)
* Built-in audio recorder
* YouTube video transcription (NEW)
* Download transcript as plaintext / JSON / SRT file (NEW)
* Save and reuse summarization prompt templates
* Tweak advanced parameters for transcription and diarization models (NEW)
* Audio playback follow (highlights transcript segment currently being played) (NEW)
* Stop or terminate running transcription jobs (NEW)
* Better reactivity and responsiveness (NEW)
* Toast notifications for all actions to provide instant status (NEW)
* Simplified deployment - single binary (Single container) (NEW)
## Screenshots
You can checkout screenshots in the app website https://scriberr.app
or in this folder on the git repo https://github.com/rishikanthc/Scriberr/tree/v1.0.0/screenshots
## Installing the Beta version
You can install and try the new beta version with the following docker compose:
```yaml
services:
scriberr:
image: ghcr.io/rishikanthc/scriberr:v1.0.0-beta1
ports:
- "8080:8080"
environment:
# OpenAI API Key - Set this to your actual API key
- OPENAI_API_KEY=${OPENAI_API_KEY:-}
# Ollama config for using Ollama for summarization and chat
- OLLAMA_BASE_URL=${OLLAMA_BASE_URL:-}
# Session Key - Generate a secure random key for production
# You can generate one with: openssl rand -base64 32
- SESSION_KEY=${SESSION_KEY:-}
# Hugging face token needed for speaker diarization
- HF_TOKEN=${HF_TOKEN:-}
# Authentication credentials - Set these for custom admin credentials
- SCRIBERR_USERNAME=${SCRIBERR_USERNAME:-admin}
- SCRIBERR_PASSWORD=${SCRIBERR_PASSWORD:-password}
volumes:
# Persist database and storage files
- ./scriberr-storage:/app/storage
restart: unless-stopped
```
# Current version v0.4.1
### Build Status
**Main Branch:**
[![Main Docker](https://github.com/rishikanthc/Scriberr/actions/workflows/Main%20Docker%20Build.yml/badge.svg)](https://github.com/rishikanthc/Scriberr/actions/workflows/Main%20Docker%20Build.yml)
[![Main CUDA Docker](https://github.com/rishikanthc/Scriberr/actions/workflows/Main%20Cuda%20Docker%20Build.yml/badge.svg)](https://github.com/rishikanthc/Scriberr/actions/workflows/Main%20Cuda%20Docker%20Build.yml)
**Nightly Branch:**
[![Nightly Docker](https://github.com/rishikanthc/Scriberr/actions/workflows/Nightly%20Docker%20Build.yml/badge.svg)](https://github.com/rishikanthc/Scriberr/actions/workflows/Nightly%20Docker%20Build.yml)
[![Nightly CUDA Docker](https://github.com/rishikanthc/Scriberr/actions/workflows/Nightly%20Cuda%20Docker%20Build.yml/badge.svg)](https://github.com/rishikanthc/Scriberr/actions/workflows/Nightly%20Cuda%20Docker%20Build.yml)
## Table of Contents
- [Features](#features)
- [Demo and Screenshots](#demo-and-screenshots)
- [Installation](#installation)
- [Requirements](#requirements)
- [Quick Start](#quick-start)
- [Clone the Repository](#clone-the-repository)
- [Configure Environment Variables](#configure-environment-variables)
- [Running with Docker Compose (CPU Only)](#running-with-docker-compose-cpu-only)
- [Running with Docker Compose (GPU Support)](#running-with-docker-compose-gpu-support)
- [Access the Application](#access-the-application)
- [Building Docker Images Manually](#building-docker-images-manually)
- [CPU Image](#cpu-image)
- [GPU Image](#gpu-image)
- [Advanced Configuration](#advanced-configuration)
- [Updating from Previous Versions](#updating-from-previous-versions)
- [Troubleshooting](#troubleshooting)
- [Contributing](#contributing)
- [License](#license)
- [Acknowledgments](#acknowledgments)
## Features
- **Fast Local Transcription**: Transcribe audio files locally using WhisperX for high performance.
- **Hardware Acceleration**: Supports both CPU and GPU (NVIDIA) acceleration.
- **Customizable Compute Settings**: Configure the number of threads, cores, and model size.
- **Speaker Diarization**: Improved speaker identification with HuggingFace models.
- **Multilingual Support**: Supports all languages that the Whisper model supports.
- **Customize Summarization**: Optionally summarize transcripts with ChatGPT or Ollama using custom prompts.
- **API Access**: Exposes API endpoints for automation and integration.
- **User-Friendly Interface**: New UI with glassmorphism design.
- **Mobile Ready**: Responsive design suitable for mobile devices.
## Demo and Screenshots
> **Note:** \
> Demo was run locally on a MacBook Air M2 using Docker.
> Performance depends on the size of the model used and the number of cores and threads assigned.
> The demo was running in development mode, so performance may be slower than production.
https://github.com/user-attachments/assets/69d0c5a8-3412-4af5-a312-f3eddebc392e
![CleanShot 2024-10-04 at 14 42 54@2x](https://github.com/user-attachments/assets/90e68ebd-695e-4043-8d51-83c704a18c5c)
![CleanShot 2024-10-04 at 14 48 31@2x](https://github.com/user-attachments/assets/a8ecfa26-84aa-4091-8f22-481f0b5e67e6)
![CleanShot 2024-10-04 at 14 49 08@2x](https://github.com/user-attachments/assets/22820b96-f982-46da-8a71-79ea73559c79)
![CleanShot 2024-10-04 at 15 11 27@2x](https://github.com/user-attachments/assets/6e10b0c1-cf97-4cf6-ab47-591b6da607ef)
## Installation
### Requirements
- **Docker** and **Docker Compose** installed on your system. [Install Docker](https://docs.docker.com/get-docker/).
- **NVIDIA GPU** (optional): If you plan to use GPU acceleration, ensure you have an NVIDIA GPU and the [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html) installed.
- **HuggingFace API Key** (required for speaker diarization): You'll need a free API key from [HuggingFace](https://huggingface.co/settings/tokens) to download diarization models.
### Quick Start
#### Clone the Repository
```bash
git clone https://github.com/rishikanthc/Scriberr.git
cd Scriberr
```
#### Configure Environment Variables
Copy the example `.env` file and adjust the settings as needed:
```bash
cp env.example .env
```
Edit the `.env` file to set your desired configuration, including:
- **`ADMIN_USERNAME`** and **`ADMIN_PASSWORD`** for accessing the web interface.
- **`OPENAI_API_KEY`** if you plan to use OpenAI's GPT models for summarization.
- **`HARDWARE_ACCEL`** set to `gpu` if you have an NVIDIA GPU.
- Other configurations as needed.
#### Running with Docker Compose (CPU Only)
To run Scriberr without GPU acceleration:
```bash
docker-compose up -d
```
This command uses the `docker-compose.yml` file and builds the Docker image using the `Dockerfile`.
#### Running with Docker Compose (GPU Support)
To run Scriberr with GPU acceleration:
```bash
docker-compose -f docker-compose.yml -f docker-compose.gpu.yml up -d
```
This command uses both `docker-compose.yml` and `docker-compose.gpu.yml` files and builds the Docker image using the `Dockerfile-gpu`.
**Note**: Ensure that you have the NVIDIA Container Toolkit installed and properly configured.
#### Access the Application
Once the containers are up and running, access the Scriberr web interface at `http://localhost:3000` (or the port you specified in the `.env` file).
### Building Docker Images Manually
If you wish to build the Docker images yourself, you can use the provided `Dockerfile` and `Dockerfile-gpu`.
#### CPU Image
```bash
docker build -t scriberr:main -f Dockerfile .
```
#### GPU Image
```bash
docker build -t scriberr:main-cuda128 -f Dockerfile-cuda128 .
```
### Advanced Configuration
The application can be customized using the following environment variables in your `.env` file.
- **`ADMIN_USERNAME`**: Username for the admin user in the web interface.
- **`ADMIN_PASSWORD`**: Password for the admin user.
- **`AI_MODEL`**: Default model to use for summarization (e.g., `"gpt-3.5-turbo"`).
- **`OLLAMA_BASE_URL`**: Base URL of your OpenAI API-compatible server if not using OpenAI (e.g., your Ollama server).
- **`OPENAI_API_KEY`**: Your OpenAI API key if using OpenAI for summarization (Or Ollama if `OLLAMA_BASE_URL` is set)
- **`DIARIZATION_MODEL`**: Default model for speaker diarization (e.g., `"pyannote/speaker-diarization@3.1"`).
- **`MODELS_DIR`**, **`WORK_DIR`**, **`AUDIO_DIR`**: Directories for models, temporary files, and uploads.
- **`BODY_SIZE_LIMIT`**: Maximum request body size (e.g., `"1G"`).
- **`HARDWARE_ACCEL`**: Set to `gpu` for GPU acceleration (NVIDIA GPU required), defaults to `cpu`.
#### Speaker Diarization Setup
##### Required Models
The application requires access to the following Hugging Face models:
* pyannote/speaker-diarization-3.1
* pyannote/segmentation-3.0
###### Setup Steps
1. Create a free account at HuggingFace if you dont already have one.
2. Generate an API token at HuggingFace Tokens.
3. Accept user conditions for the required models on Hugging Face:
- Visit pyannote/speaker-diarization-3.1 and accept the conditions.
- Visit pyannote/segmentation-3.0 and accept the conditions.
4. Enter the API token in the setup wizard when prompted. The token is only used during initial setup and is not stored permanently.
Storage and Usage
The diarization models are downloaded once and stored locally, so you wont need to provide the API key again after the initial setup.
### Updating from Previous Versions
**Important**: This release includes **breaking changes** and is **not backward compatible** with previous versions. You will lose your existing data. Please back up your data before proceeding.
Changes include:
- **Performance Improvements**: The rewrite takes advantage of Svelte 5 reactivity features.
- **Transcription Engine Change**: Switched from Whisper.cpp to **WhisperX**.
- **Improved Diarization**: Significant improvements to the diarization pipeline.
- **Simplified Setup**: Streamlined setup process with improved wizard.
- **New UI**: Implemented a new UI design with glassmorphism.
- **Multilingual Support**: Transcription and diarization now support all languages that Whisper models support.
### Troubleshooting
- **Database Connection Issues**: Ensure that the PostgreSQL container is running and accessible.
- **GPU Not Detected**: Ensure that the NVIDIA Container Toolkit is installed and that Docker is configured correctly.
- **Permission Issues**: Running Docker commands may require root permissions or being part of the `docker` group.
- **Diarization Model Download Failure**: Make sure you've entered a valid HuggingFace API key during setup.
- **CUDA failed with error out of memory**: Ensure that your GPU has enough memory to run the models. You can try reducing the batch size by adding WHISPER_BATCH_SIZE= to your .env file. The default is 16, you can reduce to 8, 4, 2, etc. (Got large-v2 running on a 1.5 hour audio file on a 3070 with 8GB VRAM using batch size of 1. Anything higher and it died.)
Check the logs for more details:
```bash
docker-compose logs -f
```
### Need Help?
If you encounter issues or have questions, feel free to open an [issue](https://github.com/rishikanthc/Scriberr/issues).
## Contributing
Contributions are welcome! Feel free to submit pull requests or open issues.
- **Fork the Repository**: Create a personal fork of the repository on GitHub.
- **Clone Your Fork**: Clone your forked repository to your local machine.
- **Create a Feature Branch**: Make a branch for your feature or fix.
- **Commit Changes**: Make your changes and commit them.
- **Push to Your Fork**: Push your changes to your fork on GitHub.
- **Submit a Pull Request**: Create a pull request to merge your changes into the main repository.
For major changes, please open an issue first to discuss what you would like to change.
## License
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
## Acknowledgments
- [OpenAI Whisper](https://github.com/openai/whisper)
- [WhisperX](https://github.com/m-bain/whisperX)
- [HuggingFace](https://huggingface.co/)
- [PyAnnote Speaker Diarization](https://huggingface.co/pyannote/speaker-diarization)
- [Ollama](https://ollama.ai/)
- Community contributors who have submitted great PRs and helped the app evolve.
---
*Thank you for your patience, support, and interest in the project. Looking forward to any and all feedback.*

View File

@@ -1,34 +0,0 @@
import type { CapacitorConfig } from '@capacitor/cli';
import { SafeArea } from '@capacitor-community/safe-area';
const config: CapacitorConfig = {
appId: 'com.scriberr.app',
appName: 'scriberr',
webDir: 'build',
server: {
cleartext: true,
allowNavigation: ['*'],
androidScheme: 'http',
iosScheme: 'http'
},
ios: {
// Disable full screen
// contentInset: 'always',
scrollEnabled: true,
limitsNavigationsToAppBoundDomains: false
},
loggingBehavior: 'debug',
plugins: {
"SafeArea": {
"enabled": true,
"customColorsForSystemBars": true,
"statusBarColor": '#000000',
"statusBarContent": 'light',
"navigationBarColor": '#000000',
"navigationBarContent": 'light',
}
}
};
export default config;

View File

@@ -1,31 +0,0 @@
#!/bin/bash
# This script checks for required directories and creates them if they don't exist
# It also ensures models are downloaded correctly
# Set default paths if not defined in environment
MODELS_DIR=${MODELS_DIR:-"/scriberr/models"}
WORK_DIR=${WORK_DIR:-"/scriberr/temp"}
AUDIO_DIR=${AUDIO_DIR:-"/scriberr/uploads"}
echo "Checking and creating required directories..."
# Create directories if they don't exist
mkdir -p "$MODELS_DIR"
mkdir -p "$WORK_DIR"
mkdir -p "$AUDIO_DIR"
echo "Setting proper permissions..."
chmod -R 755 "$MODELS_DIR"
chmod -R 755 "$WORK_DIR"
chmod -R 755 "$AUDIO_DIR"
# Check for PyTorch and WhisperX installation
echo "Checking Python dependencies..."
pip list | grep -E "torch|whisperx" || {
echo "Installing required Python packages..."
pip install torch torchaudio --index-url https://download.pytorch.org/whl/cpu
pip install whisperx
}
echo "Environment check complete. Ready to transcribe!"

View File

@@ -1,17 +0,0 @@
{
"$schema": "https://next.shadcn-svelte.com/schema.json",
"style": "new-york",
"tailwind": {
"config": "tailwind.config.ts",
"css": "src/app.css",
"baseColor": "neutral"
},
"aliases": {
"components": "$lib/components",
"utils": "$lib/utils",
"ui": "$lib/components/ui",
"hooks": "$lib/hooks"
},
"typescript": true,
"registry": "https://next.shadcn-svelte.com/registry"
}

View File

@@ -1,130 +0,0 @@
import os
import whisperx
# Configure environment variables for HuggingFace
os.environ["HF_HUB_DISABLE_TELEMETRY"] = "1"
os.environ["TRUST_REMOTE_CODE"] = "1"
# Use HuggingFace token from environment variable if available
hf_token = os.environ.get("HF_API_KEY", "")
def diarize_transcript(audio_file, transcript, device="cpu", model_name="pyannote/speaker-diarization-3.1"):
"""
Performs speaker diarization on a transcript, splitting segments by speaker changes.
Args:
audio_file (str): Path to the audio file.
transcript (dict): WhisperX transcript result with segments and words.
device (str): Device to run diarization on (e.g., 'cpu' or 'cuda').
model_name (str): Diarization model to use.
Returns:
dict: Transcript with segments split by individual speakers.
"""
try:
# Clear CUDA cache before loading diarization model
if device == "cuda":
try:
import torch
torch.cuda.empty_cache()
print("Cleared CUDA cache before diarization")
# Set memory management for PyTorch
if os.environ.get("PYTORCH_CUDA_ALLOC_CONF") is None:
os.environ["PYTORCH_CUDA_ALLOC_CONF"] = "expandable_segments:True"
print("Set PYTORCH_CUDA_ALLOC_CONF to expandable_segments:True")
except ImportError:
print("Could not import torch for CUDA memory management")
print(f"Loading diarization model: {model_name}")
diarize_model = whisperx.diarize.DiarizationPipeline(
model_name=model_name,
device=device,
use_auth_token=hf_token if hf_token else None
)
print("Diarization model loaded")
print(f"Diarizing {audio_file}")
diarize_segments = diarize_model(audio_file)
print(f"Diarization produced {len(diarize_segments)} segments")
print("Assigning speaker labels")
diarized_result = whisperx.assign_word_speakers(diarize_segments, transcript)
# Step 1: Collect all words from segments
all_words = []
for segment in diarized_result.get("segments", []):
for word in segment.get("words", []):
# Ensure word has required keys
if "start" in word and "end" in word and "word" in word:
all_words.append(word)
else:
print(f"Warning: Skipping malformed word: {word}")
# Step 2: Sort words by start time
all_words.sort(key=lambda x: x["start"])
# Step 3: Group words by consecutive speakers
new_segments = []
current_segment = None
for word in all_words:
speaker = word.get("speaker", "unknown") # Default to "unknown" if speaker is missing
if not speaker or speaker.lower() == "unknown":
speaker = "unknown" # Standardize unknown labels
if current_segment is None:
# Start the first segment
current_segment = {
"start": word["start"],
"end": word["end"],
"text": word["word"],
"speaker": speaker,
"words": [word]
}
elif speaker == current_segment["speaker"]:
# Same speaker, extend the current segment
current_segment["end"] = word["end"]
current_segment["text"] += " " + word["word"]
current_segment["words"].append(word)
else:
# Different speaker, save current segment and start a new one
new_segments.append(current_segment)
current_segment = {
"start": word["start"],
"end": word["end"],
"text": word["word"],
"speaker": speaker,
"words": [word]
}
# Step 4: Add the last segment if it exists
if current_segment:
new_segments.append(current_segment)
# Step 5: Return the new segments
print(f"Created {len(new_segments)} speaker-specific segments")
# Clear memory after processing
if device == "cuda":
try:
import torch
# Delete model to free memory
del diarize_model
# Explicit garbage collection
import gc
gc.collect()
# Clear CUDA cache again
torch.cuda.empty_cache()
print("Cleared memory after diarization")
except ImportError:
pass
return {"segments": new_segments}
except Exception as e:
print(f"Diarization failed: {str(e)}")
# Fallback: Assign "unknown" to original segments
for segment in transcript["segments"]:
segment["speaker"] = "unknown"
return transcript

View File

@@ -1,19 +0,0 @@
# This can be added when running the main docker-compose.yml file to add gpu support
# add this in your command line: docker-compose -f docker-compose.yml -f docker-compose.gpu.yml up
services:
app:
build:
context: .
dockerfile: Dockerfile-cuda128
# You can find your architecture by running: nvidia-smi if on linux
# You can find your architecture by running: system_profiler SPDisplaysDataType if on mac
# You can find your architecture by running: wmic path win32_videocontroller get name if on windows
# You will need to change the image to match your architecture, E.G. "main-cuda-11"
image: ghcr.io/rishikanthc/scriberr:main-cuda128
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]

View File

@@ -1,55 +0,0 @@
services:
app:
image: ghcr.io/rishikanthc/scriberr:${IMAGE_TAG:-main}
build:
context: .
platforms:
- linux/arm64
- linux/amd64
# No args needed as environment variables are passed at runtime
env_file:
- .env
environment:
- DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}
ports:
- "${PORT:-3000}:3000"
volumes:
- scriberr_data:/scriberr
networks:
- app-network
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:3000/health || exit 1"]
interval: 30s
timeout: 10s
retries: 5
depends_on:
db:
condition: service_healthy
restart: unless-stopped
db:
image: postgres:15-alpine
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
#ports:
# - "${POSTGRES_PORT:-5432}:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U root -d ${POSTGRES_DB}"]
interval: 5s
timeout: 5s
retries: 5
networks:
- app-network
restart: unless-stopped
networks:
app-network:
driver: bridge
volumes:
postgres_data:
scriberr_data:

View File

@@ -1,143 +0,0 @@
#!/bin/bash
set -e
# Set HARDWARE_ACCEL: 'cuda' for GPU, 'cpu' otherwise
if [ "$HARDWARE_ACCEL" = "gpu" ]; then
export HARDWARE_ACCEL='cuda'
else
export HARDWARE_ACCEL='cpu'
fi
# Function to wait for the database to be ready
wait_for_db() {
# Skip if database variables aren't set
if [ -z "$POSTGRES_USER" ] || [ -z "$POSTGRES_PASSWORD" ] || [ -z "$POSTGRES_DB" ]; then
# For production, we should require these variables
if [ "$NODE_ENV" = "production" ]; then
echo "ERROR: Database credentials required in production but not set"
echo "Please set POSTGRES_USER, POSTGRES_PASSWORD, and POSTGRES_DB environment variables"
exit 1
else
echo "Database credentials not fully set, skipping database check"
return 0
fi
fi
echo "Waiting for database to be ready..."
echo "Current DATABASE_URL: $DATABASE_URL"
until PGPASSWORD="$POSTGRES_PASSWORD" pg_isready -h $POSTGRES_HOST -p 5432 -U "$POSTGRES_USER" -d "$POSTGRES_DB"
do
echo "Database connection attempt failed. Retrying in 2 seconds..."
sleep 2
done
echo "Database is ready!"
}
# Function to install dependencies based on hardware type
install_dependencies() {
echo "Checking and installing dependencies..."
VENV_LOCATION_DIR="/scriberr/"
VENV_DIR="/scriberr/.venv"
# Create venv if it doesn't exist
if [ ! -d "$VENV_DIR" ]; then
echo "Creating virtual environment..."
uv venv --directory "$VENV_LOCATION_DIR"
echo "Virtual environment created."
else
echo "Virtual environment already exists."
fi
# Create necessary directories for model storage
echo "Setting up model directories..."
mkdir -p "${MODELS_DIR:-/scriberr/models}"
mkdir -p "${WORK_DIR:-/scriberr/temp}"
mkdir -p "${AUDIO_DIR:-/scriberr/uploads}"
chmod -R 755 "${MODELS_DIR:-/scriberr/models}"
# Set environment variables for HuggingFace
export HF_HUB_DISABLE_TELEMETRY=1
export TRUST_REMOTE_CODE=1
# Pass through HuggingFace token if provided in environment
if [ -n "$HUGGINGFACE_TOKEN" ]; then
echo "HuggingFace token provided, will be used for model downloads"
else
echo "WARNING: No HuggingFace token provided. Speaker diarization may not work correctly."
fi
# Activate venv
source "$VENV_DIR/bin/activate"
# Install Python dependencies
echo "Installing Python dependencies..."
# Install PyTorch based on hardware
if [ "$HARDWARE_ACCEL" = "cuda" ]; then
uv pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/nightly/cu128
uv pip install nvidia-cudnn-cu11==8.9.6.50
echo "PyTorch with CUDA installed."
else
uv pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu
fi
# Install remaining dependencies from requirements.txt
uv pip install -r requirements.txt
# Note: Venv remains activated so PATH is set for the Node.js application
# Install Node.js dependencies if directory is empty
echo "Checking for Node.js dependencies..."
if [ ! "$(ls -A /app/node_modules)" ]; then
echo "Installing Node.js dependencies..."
else
echo "Node.js dependencies already installed."
fi
# Build the application
if [ ! "$(ls -A /app/build)" ]; then
echo "Building the application..."
NODE_ENV=development npm run build
else
echo "Application already built."
fi
}
export VENV_DIR="/scriberr/.venv"
export LD_LIBRARY_PATH=$VENV_DIR/lib/python3.12/site-packages/nvidia/cudnn/lib
export NODE_ENV=production
# Execute the setup steps
install_dependencies
wait_for_db
# Run database migrations if DATABASE_URL is set
if [ -n "$DATABASE_URL" ]; then
echo "Creating database..."
if ! npx drizzle-kit generate; then
echo "Migration generation failed, but continuing..."
fi
if ! npx drizzle-kit migrate; then
echo "Migration failed, but continuing..."
fi
echo "Running database push..."
if ! npx drizzle-kit push; then
echo "Database push failed, but continuing..."
fi
else
# For production, DATABASE_URL is required
if [ "$NODE_ENV" = "production" ]; then
echo "ERROR: DATABASE_URL is required in production but not set"
exit 1
else
echo "DATABASE_URL not set, skipping database migrations"
fi
fi
# Start the application
echo "Starting the application..."
node build

View File

@@ -1,10 +0,0 @@
services:
db:
image: postgres
restart: always
ports:
- 5432:5432
environment:
POSTGRES_USER: root
POSTGRES_PASSWORD: mysecretpassword
POSTGRES_DB: local

View File

@@ -1,25 +0,0 @@
import { defineConfig } from 'drizzle-kit';
// Check if we're in production mode
const isProduction = process.env.NODE_ENV === 'production';
// In production, DATABASE_URL is required
if (isProduction && !process.env.DATABASE_URL) {
throw new Error('DATABASE_URL is required in production mode');
}
// Default to a placeholder URL during development/build
// At runtime in production, the real DATABASE_URL will be used
const dbUrl = process.env.DATABASE_URL || 'postgresql://placeholder:placeholder@localhost:5432/placeholder';
export default defineConfig({
schema: './src/lib/server/db/schema.ts',
dbCredentials: {
url: dbUrl
},
verbose: true,
strict: false,
dialect: 'postgresql'
});

View File

@@ -1,5 +0,0 @@
{
"version": "7",
"dialect": "postgresql",
"entries": []
}

View File

@@ -1,55 +0,0 @@
# .env file
# Docker image configuration
IMAGE_TAG=main # Docker image tag to use for building the Docker image
PORT=3000 # Port to use for running the web interface
# Database configuration
POSTGRES_PORT=5432 # Port to use for PostgreSQL database
POSTGRES_USER=root # Username for PostgreSQL database
POSTGRES_PASSWORD=mysecretpassword # Password for PostgreSQL database
POSTGRES_HOST=db # Hostname for PostgreSQL database
POSTGRES_DB=local # Database name
# Made using the variables from above. Will be removed in later versions.
# DATABASE_URL=postgres://root:mysecretpassword@db:5432/local # Database URL for connection to PostgreSQL database with credentials from above
# Application configuration
ADMIN_USERNAME=admin # Username for admin user in web interface
ADMIN_PASSWORD=password # Password for admin user in web interface
# AI configuration
# Default Model to use for transcription, can be set to any OpenAI model or Ollama model
# For ollama connections, enter the model name and version number. EG: llama3.2:latest
AI_MODEL="gpt-3.5-turbo"
# Leave blank to use default (OpenAI API), otherwise set to the base URL of your OpenAI API compatible server
# For ollama connections, enter the IP of the Ollama server, and then the port it is running on.
# Include the /v1/ or /api/v1/ path if needed (OpenWeb UI uses /api/ and ollama uses /v1/
# Example: http://192.168.1.5:11434 or http://host.docker.internal:11434
# NOTE: host.docker.internal is only available on Windows and MacOS, use the IP address of the host machine on Linux
# NOTE: localhost and 127.0.0.1 will not work, as they refer to the container itself, not the host machine
OLLAMA_BASE_URL=""
# API Keys
# NOTE:
# If using Ollama, you can leave these blank or set to a dummy value
# If using OpenAI, you must set these to your API keys
# If using a custom API compatible server, you must set these to your API keys
OPENAI_API_KEY="" # Needed for retrieving models from OpenAI, for Ollama connections, this can be left blank or set to a dummy value
# Diarization configuration
# Default Model to use for Diarization, can be set to any compatible model that supports diarization
# NOTE: This model will be downloaded automatically if it is not already present in the models directory
# NOTE: You MUST provide a valid HuggingFace API token with access to pyannote/speaker-diarization models
DIARIZATION_MODEL=pyannote/speaker-diarization@3.0
HUGGINGFACE_TOKEN="" # Required for accessing speaker diarization models from HuggingFace
# Paths
# These almost never need to be changed. They are the paths to the directories where the models and audio files are stored
MODELS_DIR=/scriberr/models
WORK_DIR=/scriberr/temp
AUDIO_DIR=/scriberr/uploads
# Server configuration
BODY_SIZE_LIMIT=1G
HARDWARE_ACCEL=cpu # Set to 'gpu' if you have a Nvidia GPU
USE_WORKER=true # Enable background processing of transcription jobs

View File

@@ -1,33 +0,0 @@
import prettier from 'eslint-config-prettier';
import js from '@eslint/js';
import svelte from 'eslint-plugin-svelte';
import globals from 'globals';
import ts from 'typescript-eslint';
export default ts.config(
js.configs.recommended,
...ts.configs.recommended,
...svelte.configs['flat/recommended'],
prettier,
...svelte.configs['flat/prettier'],
{
languageOptions: {
globals: {
...globals.browser,
...globals.node
}
}
},
{
files: ['**/*.svelte'],
languageOptions: {
parserOptions: {
parser: ts.parser
}
}
},
{
ignores: ['build/', '.svelte-kit/', 'dist/']
}
);

8073
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,75 +0,0 @@
{
"name": "scriberr",
"version": "0.0.1",
"type": "module",
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"format": "prettier --write .",
"lint": "prettier --check . && eslint .",
"db:start": "docker compose up",
"db:push": "drizzle-kit push",
"db:migrate": "drizzle-kit migrate",
"db:studio": "drizzle-kit studio"
},
"devDependencies": {
"@sveltejs/adapter-auto": "^4.0.0",
"@sveltejs/kit": "^2.17.1",
"@sveltejs/vite-plugin-svelte": "^5.0.3",
"autoprefixer": "^10.4.20",
"bits-ui": "^1.1.0",
"clsx": "^2.1.1",
"drizzle-kit": "^0.30.4",
"eslint": "^9.20.1",
"eslint-config-prettier": "^10.0.1",
"eslint-plugin-svelte": "^2.46.1",
"globals": "^15.15.0",
"lucide-svelte": "^0.475.0",
"mode-watcher": "^0.5.1",
"postcss": "^8.5.2",
"prettier": "^3.5.1",
"prettier-plugin-svelte": "^3.3.3",
"prettier-plugin-tailwindcss": "^0.6.11",
"svelte": "^5.20.0",
"svelte-check": "^4.1.4",
"svelte-sonner": "^0.3.28",
"tailwind-merge": "^3.0.1",
"tailwind-variants": "^0.3.1",
"tailwindcss": "^3.4.17",
"tailwindcss-animate": "^1.0.7",
"typescript": "^5.7.3",
"typescript-eslint": "^8.24.0",
"vite": "^6.1.0"
},
"dependencies": {
"@capacitor-community/safe-area": "6.0.0-alpha.8",
"@capacitor-community/speech-recognition": "",
"@capacitor/cli": "",
"@capacitor/core": "6.2.0",
"@capacitor/filesystem": "6.0.3",
"@capacitor/ios": "6.1.2",
"@capacitor/preferences": "6.0.3",
"@mediagrid/capacitor-native-audio": "1.2.0",
"@oslojs/crypto": "",
"@oslojs/encoding": "",
"@paralleldrive/cuid2": "",
"@sveltejs/adapter-node": "",
"@sveltejs/adapter-static": "",
"@tailwindcss/forms": "",
"@tailwindcss/postcss": "",
"@tailwindcss/typography": "",
"audiomotion-analyzer": "",
"capacitor-voice-recorder": "6.0.3",
"drizzle-orm": "",
"marked": "^15.0.7",
"openai": "",
"pg-boss": "",
"postgres": "",
"speech-recognition": "",
"svelte-file-dropzone": "",
"wavesurfer.js": ""
}
}

View File

@@ -1,7 +0,0 @@
// postcss.config.js
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};

View File

@@ -1,7 +0,0 @@
whisperx
faster-whisper
pyannote-audio
pyannote-core
pyannote-pipeline
pyannote-database
pyannote-metrics

View File

@@ -1,2 +0,0 @@
build
dist

View File

@@ -1 +0,0 @@
save-exact=true

View File

@@ -1,2 +0,0 @@
build
dist

View File

@@ -1,42 +0,0 @@
# Changelog
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
### [6.0.1](https://github.com/capacitor-community/speech-recognition/compare/v6.0.0...v6.0.1) (2024-06-28)
### Bug Fixes
* **ios:** proper isListening return ([#103](https://github.com/capacitor-community/speech-recognition/issues/103)) ([daf40a7](https://github.com/capacitor-community/speech-recognition/commit/daf40a73fda9b1caa5e84df41bf15ff687617742))
## [6.0.0](https://github.com/capacitor-community/speech-recognition/compare/v5.1.0...v6.0.0) (2024-06-07)
### ⚠ BREAKING CHANGES
* Remove deprecated permission methods (#94)
* Update to Capacitor 6 (#86)
* use correct name on rollup (#93)
### Features
* Remove deprecated permission methods ([#94](https://github.com/capacitor-community/speech-recognition/issues/94)) ([77d89b8](https://github.com/capacitor-community/speech-recognition/commit/77d89b86117a9e1adc88abfafc8c9327ea5fef8d))
* Update to Capacitor 6 ([#86](https://github.com/capacitor-community/speech-recognition/issues/86)) ([8e2f62b](https://github.com/capacitor-community/speech-recognition/commit/8e2f62b5ed37fdb8acf33c31b4e7157d03a47739))
### Bug Fixes
* correct since for isListening and listeningState ([#92](https://github.com/capacitor-community/speech-recognition/issues/92)) ([8b9445c](https://github.com/capacitor-community/speech-recognition/commit/8b9445caf09093422d761c6b3f91ed330d273047))
* **ios:** add missing listeningState stopped cases ([#95](https://github.com/capacitor-community/speech-recognition/issues/95)) ([19f98d1](https://github.com/capacitor-community/speech-recognition/commit/19f98d13b6a9454373a7d1af57e83f49fa823174))
* use correct name on rollup ([#93](https://github.com/capacitor-community/speech-recognition/issues/93)) ([d8fefbc](https://github.com/capacitor-community/speech-recognition/commit/d8fefbc13594c7949e3bc687355c7308d9f90d8d))
## [5.1.0](https://github.com/capacitor-community/speech-recognition/compare/v5.0.0...v5.1.0) (2024-03-27)
### Features
* add `isListening` method and `listeningState` listener ([#83](https://github.com/capacitor-community/speech-recognition/issues/83)) ([5a9b532](https://github.com/capacitor-community/speech-recognition/commit/5a9b532f316df7585b94e65bff77b642df5eb32e))
# Changelog
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

View File

@@ -1,66 +0,0 @@
# Contributing
This guide provides instructions for contributing to this Capacitor plugin.
## Developing
### Local Setup
1. Fork and clone the repo.
2. Install the dependencies.
```shell
npm install
```
3. Install SwiftLint if you're on macOS.
```shell
brew install swiftlint
```
### Scripts
#### `npm run build`
Build the plugin web assets and generate plugin API documentation using [`@capacitor/docgen`](https://github.com/ionic-team/capacitor-docgen).
It will compile the TypeScript code from `src/` into ESM JavaScript in `dist/esm/`. These files are used in apps with bundlers when your plugin is imported.
Then, Rollup will bundle the code into a single file at `dist/plugin.js`. This file is used in apps without bundlers by including it as a script in `index.html`.
#### `npm run verify`
Build and validate the web and native projects.
This is useful to run in CI to verify that the plugin builds for all platforms.
#### `npm run lint` / `npm run fmt`
Check formatting and code quality, autoformat/autofix if possible.
This template is integrated with ESLint, Prettier, and SwiftLint. Using these tools is completely optional, but the [Capacitor Community](https://github.com/capacitor-community/) strives to have consistent code style and structure for easier cooperation.
## Versioning
Don't change the plugin version manually, the version change is automated with `standard-version` package.
## Publishing
First run:
```shell
npm run release
```
That will update the plugin version and update the `CHANGELOG.md` file with latest changes. Then it will ask you to run:
```shell
git push --follow-tags origin master && npm publish
```
That creates a tag on gitbhub and publishes the package on npm.
Go to the [github tags section](https://github.com/capacitor-community/speech-recognition/tags), pick the latest tag and create a release for it.
> **Note**: The [`files`](https://docs.npmjs.com/cli/v7/configuring-npm/package-json#files) array in `package.json` specifies which files get published. If you rename files/directories or add files elsewhere, you may need to update it.

View File

@@ -1,17 +0,0 @@
require 'json'
package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
Pod::Spec.new do |s|
s.name = 'CapacitorCommunitySpeechRecognition'
s.version = package['version']
s.summary = package['description']
s.license = package['license']
s.homepage = package['repository']['url']
s.author = package['author']
s.source = { :git => package['repository']['url'], :tag => s.version.to_s }
s.source_files = 'ios/Plugin/**/*.{swift,h,m,c,cc,mm,cpp}'
s.ios.deployment_target = '13.0'
s.dependency 'Capacitor'
s.swift_version = '5.1'
end

View File

@@ -1,21 +0,0 @@
MIT License
Copyright (c) COPYRIGHT_YEAR COPYRIGHT_HOLDER
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.

View File

@@ -1,370 +0,0 @@
# Capacitor Speech Recognition Plugin
Capacitor community plugin for speech recognition.
## Maintainers
| Maintainer | GitHub | Social |
| --------------- | ------------------------------------------- | ------------------------------------------------ |
| Priyank Patel | [priyankpat](https://github.com/priyankpat) | [@priyankpat\_](https://twitter.com/priyankpat_) |
| Matteo Padovano | [mrbatista](https://github.com/mrbatista) | [@mrba7ista](https://twitter.com/mrba7ista) |
Maintenance Status: Actively Maintained
## Installation
To use npm
```bash
npm install @capacitor-community/speech-recognition
```
To use yarn
```bash
yarn add @capacitor-community/speech-recognition
```
Sync native files
```bash
npx cap sync
```
## iOS
iOS requires the following usage descriptions be added and filled out for your app in `Info.plist`:
- `NSSpeechRecognitionUsageDescription` (`Privacy - Speech Recognition Usage Description`)
- `NSMicrophoneUsageDescription` (`Privacy - Microphone Usage Description`)
## Android
No further action required.
## Supported methods
<docgen-index>
* [`available()`](#available)
* [`record(...)`](#record)
* [`startMicrophoneStream()`](#startmicrophonestream)
* [`stopMicrophoneStream()`](#stopmicrophonestream)
* [`stopRecording()`](#stoprecording)
* [`start(...)`](#start)
* [`stop()`](#stop)
* [`getSupportedLanguages()`](#getsupportedlanguages)
* [`isListening()`](#islistening)
* [`checkPermissions()`](#checkpermissions)
* [`requestPermissions()`](#requestpermissions)
* [`addListener('partialResults', ...)`](#addlistenerpartialresults-)
* [`addListener('listeningState', ...)`](#addlistenerlisteningstate-)
* [`removeAllListeners()`](#removealllisteners)
* [Interfaces](#interfaces)
* [Type Aliases](#type-aliases)
</docgen-index>
## Example
```typescript
import { SpeechRecognition } from "@capacitor-community/speech-recognition";
SpeechRecognition.available();
SpeechRecognition.start({
language: "en-US",
maxResults: 2,
prompt: "Say something",
partialResults: true,
popup: true,
});
// listen to partial results
SpeechRecognition.addListener("partialResults", (data: any) => {
console.log("partialResults was fired", data.matches);
});
// stop listening partial results
SpeechRecognition.removeAllListeners();
SpeechRecognition.stop();
SpeechRecognition.getSupportedLanguages();
SpeechRecognition.checkPermissions();
SpeechRecognition.requestPermissions();
SpeechRecognition.hasPermission();
SpeechRecognition.requestPermission();
```
<docgen-api>
<!--Update the source file JSDoc comments and rerun docgen to update the docs below-->
### available()
```typescript
available() => Promise<{ available: boolean; }>
```
This method will check if speech recognition feature is available on the device.
**Returns:** <code>Promise&lt;{ available: boolean; }&gt;</code>
--------------------
### record(...)
```typescript
record(options?: RecordOptions | undefined) => Promise<RecordingResult>
```
Start recording audio to a file
| Param | Type |
| ------------- | ------------------------------------------------------- |
| **`options`** | <code><a href="#recordoptions">RecordOptions</a></code> |
**Returns:** <code>Promise&lt;<a href="#recordingresult">RecordingResult</a>&gt;</code>
--------------------
### startMicrophoneStream()
```typescript
startMicrophoneStream() => Promise<RecordingResult>
```
Start streaming microphone data for visualization
**Returns:** <code>Promise&lt;<a href="#recordingresult">RecordingResult</a>&gt;</code>
--------------------
### stopMicrophoneStream()
```typescript
stopMicrophoneStream() => Promise<RecordingResult>
```
Stop streaming microphone data
**Returns:** <code>Promise&lt;<a href="#recordingresult">RecordingResult</a>&gt;</code>
--------------------
### stopRecording()
```typescript
stopRecording() => Promise<void>
```
--------------------
### start(...)
```typescript
start(options?: UtteranceOptions | undefined) => Promise<{ matches?: string[]; }>
```
This method will start to listen for utterance.
if `partialResults` is `true`, the function respond directly without result and
event `partialResults` will be emit for each partial result, until stopped.
| Param | Type |
| ------------- | ------------------------------------------------------------- |
| **`options`** | <code><a href="#utteranceoptions">UtteranceOptions</a></code> |
**Returns:** <code>Promise&lt;{ matches?: string[]; }&gt;</code>
--------------------
### stop()
```typescript
stop() => Promise<void>
```
This method will stop listening for utterance
--------------------
### getSupportedLanguages()
```typescript
getSupportedLanguages() => Promise<{ languages: any[]; }>
```
This method will return list of languages supported by the speech recognizer.
It's not available on Android 13 and newer.
**Returns:** <code>Promise&lt;{ languages: any[]; }&gt;</code>
--------------------
### isListening()
```typescript
isListening() => Promise<{ listening: boolean; }>
```
This method will check if speech recognition is listening.
**Returns:** <code>Promise&lt;{ listening: boolean; }&gt;</code>
**Since:** 5.1.0
--------------------
### checkPermissions()
```typescript
checkPermissions() => Promise<PermissionStatus>
```
Check the speech recognition permission.
**Returns:** <code>Promise&lt;<a href="#permissionstatus">PermissionStatus</a>&gt;</code>
**Since:** 5.0.0
--------------------
### requestPermissions()
```typescript
requestPermissions() => Promise<PermissionStatus>
```
Request the speech recognition permission.
**Returns:** <code>Promise&lt;<a href="#permissionstatus">PermissionStatus</a>&gt;</code>
**Since:** 5.0.0
--------------------
### addListener('partialResults', ...)
```typescript
addListener(eventName: 'partialResults', listenerFunc: (data: { matches: string[]; }) => void) => Promise<PluginListenerHandle>
```
Called when partialResults set to true and result received.
On Android it doesn't work if popup is true.
Provides partial result.
| Param | Type |
| ------------------ | ------------------------------------------------------ |
| **`eventName`** | <code>'partialResults'</code> |
| **`listenerFunc`** | <code>(data: { matches: string[]; }) =&gt; void</code> |
**Returns:** <code>Promise&lt;<a href="#pluginlistenerhandle">PluginListenerHandle</a>&gt;</code>
**Since:** 2.0.2
--------------------
### addListener('listeningState', ...)
```typescript
addListener(eventName: 'listeningState', listenerFunc: (data: { status: 'started' | 'stopped'; }) => void) => Promise<PluginListenerHandle>
```
Called when listening state changed.
| Param | Type |
| ------------------ | ------------------------------------------------------------------- |
| **`eventName`** | <code>'listeningState'</code> |
| **`listenerFunc`** | <code>(data: { status: 'started' \| 'stopped'; }) =&gt; void</code> |
**Returns:** <code>Promise&lt;<a href="#pluginlistenerhandle">PluginListenerHandle</a>&gt;</code>
**Since:** 5.1.0
--------------------
### removeAllListeners()
```typescript
removeAllListeners() => Promise<void>
```
Remove all the listeners that are attached to this plugin.
**Since:** 4.0.0
--------------------
### Interfaces
#### RecordingResult
| Prop | Type | Description |
| ------------ | ----------------------------------- | ------------------------------- |
| **`path`** | <code>string</code> | Path to the recorded audio file |
| **`status`** | <code>'started' \| 'stopped'</code> | |
#### RecordOptions
| Prop | Type |
| ---------------- | ------------------- |
| **`fileName`** | <code>string</code> |
| **`outputPath`** | <code>string</code> |
#### UtteranceOptions
| Prop | Type | Description |
| -------------------- | -------------------- | ---------------------------------------------------------------- |
| **`language`** | <code>string</code> | key returned from `getSupportedLanguages()` |
| **`maxResults`** | <code>number</code> | maximum number of results to return (5 is max) |
| **`prompt`** | <code>string</code> | prompt message to display on popup (Android only) |
| **`popup`** | <code>boolean</code> | display popup window when listening for utterance (Android only) |
| **`partialResults`** | <code>boolean</code> | return partial results if found |
#### PermissionStatus
| Prop | Type | Description | Since |
| ----------------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- |
| **`speechRecognition`** | <code><a href="#permissionstate">PermissionState</a></code> | Permission state for speechRecognition alias. On Android it requests/checks RECORD_AUDIO permission On iOS it requests/checks the speech recognition and microphone permissions. | 5.0.0 |
#### PluginListenerHandle
| Prop | Type |
| ------------ | ----------------------------------------- |
| **`remove`** | <code>() =&gt; Promise&lt;void&gt;</code> |
### Type Aliases
#### PermissionState
<code>'prompt' | 'prompt-with-rationale' | 'granted' | 'denied'</code>
</docgen-api>

View File

@@ -1 +0,0 @@
/build

View File

@@ -1,57 +0,0 @@
ext {
junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.13.2'
androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.6.1'
androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.1.5'
androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.5.1'
}
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:8.2.1'
}
}
apply plugin: 'com.android.library'
android {
namespace "com.getcapacitor.community.speechrecognition.speechrecognition"
compileSdk project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 34
defaultConfig {
minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 22
targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 34
versionCode 1
versionName '1.0'
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
lintOptions {
abortOnError false
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
}
repositories {
google()
mavenCentral()
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation project(':capacitor-android')
implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
testImplementation "junit:junit:$junitVersion"
androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
}

View File

@@ -1,20 +0,0 @@
# 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.
org.gradle.jvmargs=-Xmx1536m
# 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
# Supports AndroidX
android.useAndroidX=true

View File

@@ -1,7 +0,0 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-all.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@@ -1,248 +0,0 @@
#!/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/HEAD/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
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
# 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
if ! command -v java >/dev/null 2>&1
then
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
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
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
# 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"'
# 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 \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# 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" "$@"

View File

@@ -1,92 +0,0 @@
@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=.
@rem This is normally unused
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% equ 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% equ 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!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@@ -1,21 +0,0 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View File

@@ -1,2 +0,0 @@
include ':capacitor-android'
project(':capacitor-android').projectDir = new File('../node_modules/@capacitor/android/capacitor')

View File

@@ -1,26 +0,0 @@
package com.getcapacitor.android;
import static org.junit.Assert.*;
import android.content.Context;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
import org.junit.Test;
import org.junit.runner.RunWith;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() throws Exception {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
assertEquals("com.getcapacitor.android", appContext.getPackageName());
}
}

View File

@@ -1,11 +0,0 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<queries>
<intent>
<action android:name="android.speech.RecognitionService" />
</intent>
</queries>
</manifest>

View File

@@ -1,19 +0,0 @@
package com.getcapacitor.community.speechrecognition;
import android.Manifest;
public interface Constants {
int REQUEST_CODE_PERMISSION = 2001;
int REQUEST_CODE_SPEECH = 2002;
String IS_RECOGNITION_AVAILABLE = "isRecognitionAvailable";
String START_LISTENING = "startListening";
String STOP_LISTENING = "stopListening";
String GET_SUPPORTED_LANGUAGES = "getSupportedLanguages";
String HAS_PERMISSION = "hasPermission";
String REQUEST_PERMISSION = "requestPermission";
int MAX_RESULTS = 5;
String NOT_AVAILABLE = "Speech recognition service is not available.";
String MISSING_PERMISSION = "Missing permission";
String RECORD_AUDIO_PERMISSION = Manifest.permission.RECORD_AUDIO;
String ERROR = "Could not get list of languages";
}

View File

@@ -1,52 +0,0 @@
package com.getcapacitor.community.speechrecognition;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.speech.RecognizerIntent;
import com.getcapacitor.JSArray;
import com.getcapacitor.JSObject;
import com.getcapacitor.PluginCall;
import java.util.List;
public class Receiver extends BroadcastReceiver implements Constants {
public static final String TAG = "Receiver";
private List<String> supportedLanguagesList;
private String languagePref;
private PluginCall call;
public Receiver(PluginCall call) {
super();
this.call = call;
}
@Override
public void onReceive(Context context, Intent intent) {
Bundle extras = getResultExtras(true);
if (extras.containsKey(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE)) {
languagePref = extras.getString(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE);
}
if (extras.containsKey(RecognizerIntent.EXTRA_SUPPORTED_LANGUAGES)) {
supportedLanguagesList = extras.getStringArrayList(RecognizerIntent.EXTRA_SUPPORTED_LANGUAGES);
JSArray languagesList = new JSArray(supportedLanguagesList);
call.resolve(new JSObject().put("languages", languagesList));
return;
}
call.reject(ERROR);
}
public List<String> getSupportedLanguages() {
return supportedLanguagesList;
}
public String getLanguagePreference() {
return languagePref;
}
}

View File

@@ -1,375 +0,0 @@
package com.getcapacitor.community.speechrecognition;
import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.speech.RecognitionListener;
import android.speech.RecognizerIntent;
import android.speech.SpeechRecognizer;
import androidx.activity.result.ActivityResult;
import com.getcapacitor.JSArray;
import com.getcapacitor.JSObject;
import com.getcapacitor.Logger;
import com.getcapacitor.PermissionState;
import com.getcapacitor.Plugin;
import com.getcapacitor.PluginCall;
import com.getcapacitor.PluginMethod;
import com.getcapacitor.annotation.ActivityCallback;
import com.getcapacitor.annotation.CapacitorPlugin;
import com.getcapacitor.annotation.Permission;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.locks.ReentrantLock;
import org.json.JSONArray;
@CapacitorPlugin(
permissions = { @Permission(strings = { Manifest.permission.RECORD_AUDIO }, alias = SpeechRecognition.SPEECH_RECOGNITION) }
)
public class SpeechRecognition extends Plugin implements Constants {
public static final String TAG = "SpeechRecognition";
private static final String LISTENING_EVENT = "listeningState";
static final String SPEECH_RECOGNITION = "speechRecognition";
private Receiver languageReceiver;
private SpeechRecognizer speechRecognizer;
private final ReentrantLock lock = new ReentrantLock();
private boolean listening = false;
private JSONArray previousPartialResults = new JSONArray();
@Override
public void load() {
super.load();
bridge
.getWebView()
.post(
() -> {
speechRecognizer = SpeechRecognizer.createSpeechRecognizer(bridge.getActivity());
SpeechRecognitionListener listener = new SpeechRecognitionListener();
speechRecognizer.setRecognitionListener(listener);
Logger.info(getLogTag(), "Instantiated SpeechRecognizer in load()");
}
);
}
@PluginMethod
public void available(PluginCall call) {
Logger.info(getLogTag(), "Called for available(): " + isSpeechRecognitionAvailable());
boolean val = isSpeechRecognitionAvailable();
JSObject result = new JSObject();
result.put("available", val);
call.resolve(result);
}
@PluginMethod
public void start(PluginCall call) {
if (!isSpeechRecognitionAvailable()) {
call.unavailable(NOT_AVAILABLE);
return;
}
if (getPermissionState(SPEECH_RECOGNITION) != PermissionState.GRANTED) {
call.reject(MISSING_PERMISSION);
return;
}
String language = call.getString("language", Locale.getDefault().toString());
int maxResults = call.getInt("maxResults", MAX_RESULTS);
String prompt = call.getString("prompt", null);
boolean partialResults = call.getBoolean("partialResults", false);
boolean popup = call.getBoolean("popup", false);
beginListening(language, maxResults, prompt, partialResults, popup, call);
}
@PluginMethod
public void stop(final PluginCall call) {
try {
stopListening();
} catch (Exception ex) {
call.reject(ex.getLocalizedMessage());
}
}
@PluginMethod
public void getSupportedLanguages(PluginCall call) {
if (languageReceiver == null) {
languageReceiver = new Receiver(call);
}
List<String> supportedLanguages = languageReceiver.getSupportedLanguages();
if (supportedLanguages != null) {
JSONArray languages = new JSONArray(supportedLanguages);
call.resolve(new JSObject().put("languages", languages));
return;
}
Intent detailsIntent = new Intent(RecognizerIntent.ACTION_GET_LANGUAGE_DETAILS);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
detailsIntent.setPackage("com.google.android.googlequicksearchbox");
}
bridge.getActivity().sendOrderedBroadcast(detailsIntent, null, languageReceiver, null, Activity.RESULT_OK, null, null);
}
@PluginMethod
public void isListening(PluginCall call) {
call.resolve(new JSObject().put("listening", SpeechRecognition.this.listening));
}
@ActivityCallback
private void listeningResult(PluginCall call, ActivityResult result) {
if (call == null) {
return;
}
int resultCode = result.getResultCode();
if (resultCode == Activity.RESULT_OK) {
try {
ArrayList<String> matchesList = result.getData().getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
JSObject resultObj = new JSObject();
resultObj.put("matches", new JSArray(matchesList));
call.resolve(resultObj);
} catch (Exception ex) {
call.reject(ex.getMessage());
}
} else {
call.reject(Integer.toString(resultCode));
}
SpeechRecognition.this.lock.lock();
SpeechRecognition.this.listening(false);
SpeechRecognition.this.lock.unlock();
}
private boolean isSpeechRecognitionAvailable() {
return SpeechRecognizer.isRecognitionAvailable(bridge.getContext());
}
private void listening(boolean value) {
this.listening = value;
}
private void beginListening(
String language,
int maxResults,
String prompt,
final boolean partialResults,
boolean showPopup,
PluginCall call
) {
Logger.info(getLogTag(), "Beginning to listen for audible speech");
final Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, language);
intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, maxResults);
intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, bridge.getActivity().getPackageName());
intent.putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, partialResults);
intent.putExtra("android.speech.extra.DICTATION_MODE", partialResults);
if (prompt != null) {
intent.putExtra(RecognizerIntent.EXTRA_PROMPT, prompt);
}
if (showPopup) {
startActivityForResult(call, intent, "listeningResult");
} else {
bridge
.getWebView()
.post(
() -> {
try {
SpeechRecognition.this.lock.lock();
if (speechRecognizer != null) {
speechRecognizer.cancel();
speechRecognizer.destroy();
speechRecognizer = null;
}
speechRecognizer = SpeechRecognizer.createSpeechRecognizer(bridge.getActivity());
SpeechRecognitionListener listener = new SpeechRecognitionListener();
listener.setCall(call);
listener.setPartialResults(partialResults);
speechRecognizer.setRecognitionListener(listener);
speechRecognizer.startListening(intent);
SpeechRecognition.this.listening(true);
if (partialResults) {
call.resolve();
}
} catch (Exception ex) {
call.reject(ex.getMessage());
} finally {
SpeechRecognition.this.lock.unlock();
}
}
);
}
}
private void stopListening() {
bridge
.getWebView()
.post(
() -> {
try {
SpeechRecognition.this.lock.lock();
if (SpeechRecognition.this.listening) {
speechRecognizer.stopListening();
SpeechRecognition.this.listening(false);
}
} catch (Exception ex) {
throw ex;
} finally {
SpeechRecognition.this.lock.unlock();
}
}
);
}
private class SpeechRecognitionListener implements RecognitionListener {
private PluginCall call;
private boolean partialResults;
public void setCall(PluginCall call) {
this.call = call;
}
public void setPartialResults(boolean partialResults) {
this.partialResults = partialResults;
}
@Override
public void onReadyForSpeech(Bundle params) {}
@Override
public void onBeginningOfSpeech() {
try {
SpeechRecognition.this.lock.lock();
// Notify listeners that recording has started
JSObject ret = new JSObject();
ret.put("status", "started");
SpeechRecognition.this.notifyListeners(LISTENING_EVENT, ret);
} finally {
SpeechRecognition.this.lock.unlock();
}
}
@Override
public void onRmsChanged(float rmsdB) {}
@Override
public void onBufferReceived(byte[] buffer) {}
@Override
public void onEndOfSpeech() {
bridge
.getWebView()
.post(
() -> {
try {
SpeechRecognition.this.lock.lock();
SpeechRecognition.this.listening(false);
JSObject ret = new JSObject();
ret.put("status", "stopped");
SpeechRecognition.this.notifyListeners(LISTENING_EVENT, ret);
} finally {
SpeechRecognition.this.lock.unlock();
}
}
);
}
@Override
public void onError(int error) {
SpeechRecognition.this.stopListening();
String errorMssg = getErrorText(error);
if (this.call != null) {
call.reject(errorMssg);
}
}
@Override
public void onResults(Bundle results) {
ArrayList<String> matches = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
try {
JSArray jsArray = new JSArray(matches);
if (this.call != null) {
if (!this.partialResults) {
this.call.resolve(new JSObject().put("status", "success").put("matches", jsArray));
} else {
JSObject ret = new JSObject();
ret.put("matches", jsArray);
notifyListeners("partialResults", ret);
}
}
} catch (Exception ex) {
this.call.resolve(new JSObject().put("status", "error").put("message", ex.getMessage()));
}
}
@Override
public void onPartialResults(Bundle partialResults) {
ArrayList<String> matches = partialResults.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
JSArray matchesJSON = new JSArray(matches);
try {
if (matches != null && matches.size() > 0 && !previousPartialResults.equals(matchesJSON)) {
previousPartialResults = matchesJSON;
JSObject ret = new JSObject();
ret.put("matches", previousPartialResults);
notifyListeners("partialResults", ret);
}
} catch (Exception ex) {}
}
@Override
public void onEvent(int eventType, Bundle params) {}
}
private String getErrorText(int errorCode) {
String message;
switch (errorCode) {
case SpeechRecognizer.ERROR_AUDIO:
message = "Audio recording error";
break;
case SpeechRecognizer.ERROR_CLIENT:
message = "Client side error";
break;
case SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS:
message = "Insufficient permissions";
break;
case SpeechRecognizer.ERROR_NETWORK:
message = "Network error";
break;
case SpeechRecognizer.ERROR_NETWORK_TIMEOUT:
message = "Network timeout";
break;
case SpeechRecognizer.ERROR_NO_MATCH:
message = "No match";
break;
case SpeechRecognizer.ERROR_RECOGNIZER_BUSY:
message = "RecognitionService busy";
break;
case SpeechRecognizer.ERROR_SERVER:
message = "error from server";
break;
case SpeechRecognizer.ERROR_SPEECH_TIMEOUT:
message = "No speech input";
break;
default:
message = "Didn't understand, please try again.";
break;
}
return message;
}
}

View File

@@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.getcapacitor.BridgeActivity"
>
<WebView
android:id="@+id/webview"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -1,3 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
</resources>

View File

@@ -1,3 +0,0 @@
<resources>
<string name="my_string">Just a simple string</string>
</resources>

View File

@@ -1,3 +0,0 @@
<resources>
</resources>

View File

@@ -1,18 +0,0 @@
package com.getcapacitor;
import static org.junit.Assert.*;
import org.junit.Test;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() throws Exception {
assertEquals(4, 2 + 2);
}
}

View File

@@ -1,439 +0,0 @@
{
"api": {
"name": "SpeechRecognitionPlugin",
"slug": "speechrecognitionplugin",
"docs": "",
"tags": [],
"methods": [
{
"name": "available",
"signature": "() => Promise<{ available: boolean; }>",
"parameters": [],
"returns": "Promise<{ available: boolean; }>",
"tags": [
{
"name": "param",
"text": "none"
},
{
"name": "returns",
"text": "available - boolean true/false for availability"
}
],
"docs": "This method will check if speech recognition feature is available on the device.",
"complexTypes": [],
"slug": "available"
},
{
"name": "record",
"signature": "(options?: RecordOptions | undefined) => Promise<RecordingResult>",
"parameters": [
{
"name": "options",
"docs": "",
"type": "RecordOptions | undefined"
}
],
"returns": "Promise<RecordingResult>",
"tags": [
{
"name": "returns",
"text": "Promise with the path to the recorded file"
}
],
"docs": "Start recording audio to a file",
"complexTypes": [
"RecordingResult",
"RecordOptions"
],
"slug": "record"
},
{
"name": "startMicrophoneStream",
"signature": "() => Promise<RecordingResult>",
"parameters": [],
"returns": "Promise<RecordingResult>",
"tags": [],
"docs": "Start streaming microphone data for visualization",
"complexTypes": [
"RecordingResult"
],
"slug": "startmicrophonestream"
},
{
"name": "stopMicrophoneStream",
"signature": "() => Promise<RecordingResult>",
"parameters": [],
"returns": "Promise<RecordingResult>",
"tags": [],
"docs": "Stop streaming microphone data",
"complexTypes": [
"RecordingResult"
],
"slug": "stopmicrophonestream"
},
{
"name": "stopRecording",
"signature": "() => Promise<void>",
"parameters": [],
"returns": "Promise<void>",
"tags": [],
"docs": "",
"complexTypes": [],
"slug": "stoprecording"
},
{
"name": "start",
"signature": "(options?: UtteranceOptions | undefined) => Promise<{ matches?: string[]; }>",
"parameters": [
{
"name": "options",
"docs": "",
"type": "UtteranceOptions | undefined"
}
],
"returns": "Promise<{ matches?: string[] | undefined; }>",
"tags": [
{
"name": "param",
"text": "options"
},
{
"name": "returns",
"text": "void or array of string results"
}
],
"docs": "This method will start to listen for utterance.\n\nif `partialResults` is `true`, the function respond directly without result and\nevent `partialResults` will be emit for each partial result, until stopped.",
"complexTypes": [
"UtteranceOptions"
],
"slug": "start"
},
{
"name": "stop",
"signature": "() => Promise<void>",
"parameters": [],
"returns": "Promise<void>",
"tags": [
{
"name": "param",
"text": "none"
},
{
"name": "returns",
"text": "void"
}
],
"docs": "This method will stop listening for utterance",
"complexTypes": [],
"slug": "stop"
},
{
"name": "getSupportedLanguages",
"signature": "() => Promise<{ languages: any[]; }>",
"parameters": [],
"returns": "Promise<{ languages: any[]; }>",
"tags": [
{
"name": "param",
"text": "none"
},
{
"name": "returns",
"text": "languages - array string of languages"
}
],
"docs": "This method will return list of languages supported by the speech recognizer.\n\nIt's not available on Android 13 and newer.",
"complexTypes": [],
"slug": "getsupportedlanguages"
},
{
"name": "isListening",
"signature": "() => Promise<{ listening: boolean; }>",
"parameters": [],
"returns": "Promise<{ listening: boolean; }>",
"tags": [
{
"name": "param",
"text": "none"
},
{
"name": "returns",
"text": "boolean true/false if speech recognition is currently listening"
},
{
"name": "since",
"text": "5.1.0"
}
],
"docs": "This method will check if speech recognition is listening.",
"complexTypes": [],
"slug": "islistening"
},
{
"name": "checkPermissions",
"signature": "() => Promise<PermissionStatus>",
"parameters": [],
"returns": "Promise<PermissionStatus>",
"tags": [
{
"name": "since",
"text": "5.0.0"
}
],
"docs": "Check the speech recognition permission.",
"complexTypes": [
"PermissionStatus"
],
"slug": "checkpermissions"
},
{
"name": "requestPermissions",
"signature": "() => Promise<PermissionStatus>",
"parameters": [],
"returns": "Promise<PermissionStatus>",
"tags": [
{
"name": "since",
"text": "5.0.0"
}
],
"docs": "Request the speech recognition permission.",
"complexTypes": [
"PermissionStatus"
],
"slug": "requestpermissions"
},
{
"name": "addListener",
"signature": "(eventName: 'partialResults', listenerFunc: (data: { matches: string[]; }) => void) => Promise<PluginListenerHandle>",
"parameters": [
{
"name": "eventName",
"docs": "",
"type": "'partialResults'"
},
{
"name": "listenerFunc",
"docs": "",
"type": "(data: { matches: string[]; }) => void"
}
],
"returns": "Promise<PluginListenerHandle>",
"tags": [
{
"name": "since",
"text": "2.0.2"
}
],
"docs": "Called when partialResults set to true and result received.\n\nOn Android it doesn't work if popup is true.\n\nProvides partial result.",
"complexTypes": [
"PluginListenerHandle"
],
"slug": "addlistenerpartialresults-"
},
{
"name": "addListener",
"signature": "(eventName: 'listeningState', listenerFunc: (data: { status: 'started' | 'stopped'; }) => void) => Promise<PluginListenerHandle>",
"parameters": [
{
"name": "eventName",
"docs": "",
"type": "'listeningState'"
},
{
"name": "listenerFunc",
"docs": "",
"type": "(data: { status: 'started' | 'stopped'; }) => void"
}
],
"returns": "Promise<PluginListenerHandle>",
"tags": [
{
"name": "since",
"text": "5.1.0"
}
],
"docs": "Called when listening state changed.",
"complexTypes": [
"PluginListenerHandle"
],
"slug": "addlistenerlisteningstate-"
},
{
"name": "removeAllListeners",
"signature": "() => Promise<void>",
"parameters": [],
"returns": "Promise<void>",
"tags": [
{
"name": "since",
"text": "4.0.0"
}
],
"docs": "Remove all the listeners that are attached to this plugin.",
"complexTypes": [],
"slug": "removealllisteners"
}
],
"properties": []
},
"interfaces": [
{
"name": "RecordingResult",
"slug": "recordingresult",
"docs": "",
"tags": [],
"methods": [],
"properties": [
{
"name": "path",
"tags": [],
"docs": "Path to the recorded audio file",
"complexTypes": [],
"type": "string"
},
{
"name": "status",
"tags": [],
"docs": "",
"complexTypes": [],
"type": "'started' | 'stopped' | undefined"
}
]
},
{
"name": "RecordOptions",
"slug": "recordoptions",
"docs": "",
"tags": [],
"methods": [],
"properties": [
{
"name": "fileName",
"tags": [],
"docs": "",
"complexTypes": [],
"type": "string | undefined"
},
{
"name": "outputPath",
"tags": [],
"docs": "",
"complexTypes": [],
"type": "string | undefined"
}
]
},
{
"name": "UtteranceOptions",
"slug": "utteranceoptions",
"docs": "",
"tags": [],
"methods": [],
"properties": [
{
"name": "language",
"tags": [],
"docs": "key returned from `getSupportedLanguages()`",
"complexTypes": [],
"type": "string | undefined"
},
{
"name": "maxResults",
"tags": [],
"docs": "maximum number of results to return (5 is max)",
"complexTypes": [],
"type": "number | undefined"
},
{
"name": "prompt",
"tags": [],
"docs": "prompt message to display on popup (Android only)",
"complexTypes": [],
"type": "string | undefined"
},
{
"name": "popup",
"tags": [],
"docs": "display popup window when listening for utterance (Android only)",
"complexTypes": [],
"type": "boolean | undefined"
},
{
"name": "partialResults",
"tags": [],
"docs": "return partial results if found",
"complexTypes": [],
"type": "boolean | undefined"
}
]
},
{
"name": "PermissionStatus",
"slug": "permissionstatus",
"docs": "",
"tags": [],
"methods": [],
"properties": [
{
"name": "speechRecognition",
"tags": [
{
"text": "5.0.0",
"name": "since"
}
],
"docs": "Permission state for speechRecognition alias.\n\nOn Android it requests/checks RECORD_AUDIO permission\n\nOn iOS it requests/checks the speech recognition and microphone permissions.",
"complexTypes": [
"PermissionState"
],
"type": "PermissionState"
}
]
},
{
"name": "PluginListenerHandle",
"slug": "pluginlistenerhandle",
"docs": "",
"tags": [],
"methods": [],
"properties": [
{
"name": "remove",
"tags": [],
"docs": "",
"complexTypes": [],
"type": "() => Promise<void>"
}
]
}
],
"enums": [],
"typeAliases": [
{
"name": "PermissionState",
"slug": "permissionstate",
"docs": "",
"types": [
{
"text": "'prompt'",
"complexTypes": []
},
{
"text": "'prompt-with-rationale'",
"complexTypes": []
},
{
"text": "'granted'",
"complexTypes": []
},
{
"text": "'denied'",
"complexTypes": []
}
]
}
],
"pluginConfigs": []
}

View File

@@ -1,153 +0,0 @@
import type { PermissionState, PluginListenerHandle } from '@capacitor/core';
export interface PermissionStatus {
/**
* Permission state for speechRecognition alias.
*
* On Android it requests/checks RECORD_AUDIO permission
*
* On iOS it requests/checks the speech recognition and microphone permissions.
*
* @since 5.0.0
*/
speechRecognition: PermissionState;
}
export interface RecordOptions {
fileName?: string;
outputPath?: string;
}
export interface RecordingResult {
/**
* Path to the recorded audio file
*/
path: string;
status?: 'started' | 'stopped';
}
export interface AudioData {
buffer: number[];
}
export interface SpeechRecognitionPlugin {
/**
* This method will check if speech recognition feature is available on the device.
* @param none
* @returns available - boolean true/false for availability
*/
available(): Promise<{
available: boolean;
}>;
/**
* Start recording audio to a file
* @returns Promise with the path to the recorded file
*/
record(options?: RecordOptions): Promise<RecordingResult>;
/**
* Start streaming microphone data for visualization
*/
startMicrophoneStream(): Promise<RecordingResult>;
/**
* Stop streaming microphone data
*/
stopMicrophoneStream(): Promise<RecordingResult>; /**
* Stop the current recording
* @returns Promise that resolves when recording is stopped
*/
stopRecording(): Promise<void>;
/**
* This method will start to listen for utterance.
*
* if `partialResults` is `true`, the function respond directly without result and
* event `partialResults` will be emit for each partial result, until stopped.
*
* @param options
* @returns void or array of string results
*/
start(options?: UtteranceOptions): Promise<{
matches?: string[];
}>;
/**
* This method will stop listening for utterance
* @param none
* @returns void
*/
stop(): Promise<void>;
/**
* This method will return list of languages supported by the speech recognizer.
*
* It's not available on Android 13 and newer.
*
* @param none
* @returns languages - array string of languages
*/
getSupportedLanguages(): Promise<{
languages: any[];
}>;
/**
* This method will check if speech recognition is listening.
* @param none
* @returns boolean true/false if speech recognition is currently listening
*
* @since 5.1.0
*/
isListening(): Promise<{
listening: boolean;
}>;
/**
* Check the speech recognition permission.
*
* @since 5.0.0
*/
checkPermissions(): Promise<PermissionStatus>;
/**
* Request the speech recognition permission.
*
* @since 5.0.0
*/
requestPermissions(): Promise<PermissionStatus>;
/**
* Called when partialResults set to true and result received.
*
* On Android it doesn't work if popup is true.
*
* Provides partial result.
*
* @since 2.0.2
*/
addListener(eventName: 'partialResults', listenerFunc: (data: {
matches: string[];
}) => void): Promise<PluginListenerHandle>;
/**
* Called when listening state changed.
*
* @since 5.1.0
*/
addListener(eventName: 'listeningState', listenerFunc: (data: {
status: 'started' | 'stopped';
}) => void): Promise<PluginListenerHandle>;
/**
* Remove all the listeners that are attached to this plugin.
*
* @since 4.0.0
*/
removeAllListeners(): Promise<void>;
}
export interface UtteranceOptions {
/**
* key returned from `getSupportedLanguages()`
*/
language?: string;
/**
* maximum number of results to return (5 is max)
*/
maxResults?: number;
/**
* prompt message to display on popup (Android only)
*/
prompt?: string;
/**
* display popup window when listening for utterance (Android only)
*/
popup?: boolean;
/**
* return partial results if found
*/
partialResults?: boolean;
}

View File

@@ -1,2 +0,0 @@
export {};
//# sourceMappingURL=definitions.js.map

View File

@@ -1 +0,0 @@
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["import type { PermissionState, PluginListenerHandle } from '@capacitor/core';\n\nexport interface PermissionStatus {\n /**\n * Permission state for speechRecognition alias.\n *\n * On Android it requests/checks RECORD_AUDIO permission\n *\n * On iOS it requests/checks the speech recognition and microphone permissions.\n *\n * @since 5.0.0\n */\n speechRecognition: PermissionState;\n}\n\nexport interface RecordOptions {\n fileName?: string;\n outputPath?: string;\n}\n\nexport interface RecordingResult {\n /**\n * Path to the recorded audio file\n */\n path: string;\n status?: 'started' | 'stopped';\n}\n\nexport interface AudioData {\n buffer: number[];\n}\n\n\nexport interface SpeechRecognitionPlugin {\n /**\n * This method will check if speech recognition feature is available on the device.\n * @param none\n * @returns available - boolean true/false for availability\n */\n available(): Promise<{ available: boolean }>;\n /**\n * Start recording audio to a file\n * @returns Promise with the path to the recorded file\n */\n record(options?: RecordOptions): Promise<RecordingResult>;\n\n/**\n * Start streaming microphone data for visualization\n */\n startMicrophoneStream(): Promise<RecordingResult>;\n\n /**\n * Stop streaming microphone data\n */\n stopMicrophoneStream(): Promise<RecordingResult>; /**\n * Stop the current recording\n * @returns Promise that resolves when recording is stopped\n */\n stopRecording(): Promise<void>;\n /**\n * This method will start to listen for utterance.\n *\n * if `partialResults` is `true`, the function respond directly without result and\n * event `partialResults` will be emit for each partial result, until stopped.\n *\n * @param options\n * @returns void or array of string results\n */\n start(options?: UtteranceOptions): Promise<{ matches?: string[] }>;\n /**\n * This method will stop listening for utterance\n * @param none\n * @returns void\n */\n stop(): Promise<void>;\n /**\n * This method will return list of languages supported by the speech recognizer.\n *\n * It's not available on Android 13 and newer.\n *\n * @param none\n * @returns languages - array string of languages\n */\n getSupportedLanguages(): Promise<{ languages: any[] }>;\n /**\n * This method will check if speech recognition is listening.\n * @param none\n * @returns boolean true/false if speech recognition is currently listening\n *\n * @since 5.1.0\n */\n isListening(): Promise<{ listening: boolean }>;\n /**\n * Check the speech recognition permission.\n *\n * @since 5.0.0\n */\n checkPermissions(): Promise<PermissionStatus>;\n /**\n * Request the speech recognition permission.\n *\n * @since 5.0.0\n */\n requestPermissions(): Promise<PermissionStatus>;\n /**\n * Called when partialResults set to true and result received.\n *\n * On Android it doesn't work if popup is true.\n *\n * Provides partial result.\n *\n * @since 2.0.2\n */\n addListener(\n eventName: 'partialResults',\n listenerFunc: (data: { matches: string[] }) => void,\n ): Promise<PluginListenerHandle>;\n\n /**\n * Called when listening state changed.\n *\n * @since 5.1.0\n */\n addListener(\n eventName: 'listeningState',\n listenerFunc: (data: { status: 'started' | 'stopped' }) => void,\n ): Promise<PluginListenerHandle>;\n /**\n * Remove all the listeners that are attached to this plugin.\n *\n * @since 4.0.0\n */\n removeAllListeners(): Promise<void>;\n}\n\nexport interface UtteranceOptions {\n /**\n * key returned from `getSupportedLanguages()`\n */\n language?: string;\n /**\n * maximum number of results to return (5 is max)\n */\n maxResults?: number;\n /**\n * prompt message to display on popup (Android only)\n */\n prompt?: string;\n /**\n * display popup window when listening for utterance (Android only)\n */\n popup?: boolean;\n /**\n * return partial results if found\n */\n partialResults?: boolean;\n}\n"]}

View File

@@ -1,4 +0,0 @@
import type { SpeechRecognitionPlugin } from './definitions';
declare const SpeechRecognition: SpeechRecognitionPlugin;
export * from './definitions';
export { SpeechRecognition };

View File

@@ -1,7 +0,0 @@
import { registerPlugin } from '@capacitor/core';
const SpeechRecognition = registerPlugin('SpeechRecognition', {
web: () => import('./web').then(m => new m.SpeechRecognitionWeb()),
});
export * from './definitions';
export { SpeechRecognition };
//# sourceMappingURL=index.js.map

View File

@@ -1 +0,0 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAIjD,MAAM,iBAAiB,GAAG,cAAc,CACtC,mBAAmB,EACnB;IACE,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,oBAAoB,EAAE,CAAC;CACnE,CACF,CAAC;AAEF,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,iBAAiB,EAAE,CAAC","sourcesContent":["import { registerPlugin } from '@capacitor/core';\n\nimport type { SpeechRecognitionPlugin } from './definitions';\n\nconst SpeechRecognition = registerPlugin<SpeechRecognitionPlugin>(\n 'SpeechRecognition',\n {\n web: () => import('./web').then(m => new m.SpeechRecognitionWeb()),\n },\n);\n\nexport * from './definitions';\nexport { SpeechRecognition };\n"]}

View File

@@ -1,29 +0,0 @@
import { WebPlugin } from '@capacitor/core';
import type { PermissionStatus, SpeechRecognitionPlugin, UtteranceOptions, RecordingResult, RecordOptions } from './definitions';
export declare class SpeechRecognitionWeb extends WebPlugin implements SpeechRecognitionPlugin {
available(): Promise<{
available: boolean;
}>;
startMicrophoneStream(): Promise<RecordingResult>;
stopMicrophoneStream(): Promise<RecordingResult>;
record(_options?: RecordOptions): Promise<RecordingResult>;
stopRecording(): Promise<void>;
start(_options?: UtteranceOptions): Promise<{
matches?: string[];
}>;
stop(): Promise<void>;
getSupportedLanguages(): Promise<{
languages: any[];
}>;
hasPermission(): Promise<{
permission: boolean;
}>;
isListening(): Promise<{
listening: boolean;
}>;
requestPermission(): Promise<void>;
checkPermissions(): Promise<PermissionStatus>;
requestPermissions(): Promise<PermissionStatus>;
}
declare const SpeechRecognition: SpeechRecognitionWeb;
export { SpeechRecognition };

View File

@@ -1,45 +0,0 @@
import { WebPlugin } from '@capacitor/core';
export class SpeechRecognitionWeb extends WebPlugin {
available() {
throw this.unimplemented('Method not implemented on web.');
}
async startMicrophoneStream() {
throw this.unimplemented('Not implemented on web.');
}
async stopMicrophoneStream() {
throw this.unimplemented('Not implemented on web.');
}
async record(_options) {
throw this.unimplemented('Not implemented on web.');
}
async stopRecording() {
throw this.unimplemented('Not implemented on web.');
}
start(_options) {
throw this.unimplemented('Method not implemented on web.');
}
stop() {
throw this.unimplemented('Method not implemented on web.');
}
getSupportedLanguages() {
throw this.unimplemented('Method not implemented on web.');
}
hasPermission() {
throw this.unimplemented('Method not implemented on web.');
}
isListening() {
throw this.unimplemented('Method not implemented on web.');
}
requestPermission() {
throw this.unimplemented('Method not implemented on web.');
}
checkPermissions() {
throw this.unimplemented('Method not implemented on web.');
}
requestPermissions() {
throw this.unimplemented('Method not implemented on web.');
}
}
const SpeechRecognition = new SpeechRecognitionWeb();
export { SpeechRecognition };
//# sourceMappingURL=web.js.map

View File

@@ -1 +0,0 @@
{"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAU5C,MAAM,OAAO,oBACX,SAAQ,SAAS;IAGjB,SAAS;QACP,MAAM,IAAI,CAAC,aAAa,CAAC,gCAAgC,CAAC,CAAC;IAC7D,CAAC;IACD,KAAK,CAAC,qBAAqB;QACzB,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC,CAAC;IACtD,CAAC;IACD,KAAK,CAAC,oBAAoB;QACxB,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC,CAAC;IACtD,CAAC;IACD,KAAK,CAAC,MAAM,CAAC,QAAwB;QACnC,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC,CAAC;IACtD,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAAC,CAAC;IACtD,CAAC;IACD,KAAK,CAAC,QAA2B;QAC/B,MAAM,IAAI,CAAC,aAAa,CAAC,gCAAgC,CAAC,CAAC;IAC7D,CAAC;IACD,IAAI;QACF,MAAM,IAAI,CAAC,aAAa,CAAC,gCAAgC,CAAC,CAAC;IAC7D,CAAC;IACD,qBAAqB;QACnB,MAAM,IAAI,CAAC,aAAa,CAAC,gCAAgC,CAAC,CAAC;IAC7D,CAAC;IACD,aAAa;QACX,MAAM,IAAI,CAAC,aAAa,CAAC,gCAAgC,CAAC,CAAC;IAC7D,CAAC;IACD,WAAW;QACT,MAAM,IAAI,CAAC,aAAa,CAAC,gCAAgC,CAAC,CAAC;IAC7D,CAAC;IACD,iBAAiB;QACf,MAAM,IAAI,CAAC,aAAa,CAAC,gCAAgC,CAAC,CAAC;IAC7D,CAAC;IACD,gBAAgB;QACd,MAAM,IAAI,CAAC,aAAa,CAAC,gCAAgC,CAAC,CAAC;IAC7D,CAAC;IACD,kBAAkB;QAChB,MAAM,IAAI,CAAC,aAAa,CAAC,gCAAgC,CAAC,CAAC;IAC7D,CAAC;CACF;AAED,MAAM,iBAAiB,GAAG,IAAI,oBAAoB,EAAE,CAAC;AAErD,OAAO,EAAE,iBAAiB,EAAE,CAAC","sourcesContent":["import { WebPlugin } from '@capacitor/core';\n\nimport type {\n PermissionStatus,\n SpeechRecognitionPlugin,\n UtteranceOptions,\n RecordingResult,\n RecordOptions\n} from './definitions';\n\nexport class SpeechRecognitionWeb\n extends WebPlugin\n implements SpeechRecognitionPlugin\n{\n available(): Promise<{ available: boolean }> {\n throw this.unimplemented('Method not implemented on web.');\n }\n async startMicrophoneStream(): Promise<RecordingResult> {\n throw this.unimplemented('Not implemented on web.');\n }\n async stopMicrophoneStream(): Promise<RecordingResult> {\n throw this.unimplemented('Not implemented on web.');\n }\n async record(_options?: RecordOptions): Promise<RecordingResult> {\n throw this.unimplemented('Not implemented on web.');\n }\n\n async stopRecording(): Promise<void> {\n throw this.unimplemented('Not implemented on web.');\n }\n start(_options?: UtteranceOptions): Promise<{ matches?: string[] }> {\n throw this.unimplemented('Method not implemented on web.');\n }\n stop(): Promise<void> {\n throw this.unimplemented('Method not implemented on web.');\n }\n getSupportedLanguages(): Promise<{ languages: any[] }> {\n throw this.unimplemented('Method not implemented on web.');\n }\n hasPermission(): Promise<{ permission: boolean }> {\n throw this.unimplemented('Method not implemented on web.');\n }\n isListening(): Promise<{ listening: boolean }> {\n throw this.unimplemented('Method not implemented on web.');\n }\n requestPermission(): Promise<void> {\n throw this.unimplemented('Method not implemented on web.');\n }\n checkPermissions(): Promise<PermissionStatus> {\n throw this.unimplemented('Method not implemented on web.');\n }\n requestPermissions(): Promise<PermissionStatus> {\n throw this.unimplemented('Method not implemented on web.');\n }\n}\n\nconst SpeechRecognition = new SpeechRecognitionWeb();\n\nexport { SpeechRecognition };\n"]}

View File

@@ -1,556 +0,0 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 48;
objects = {
/* Begin PBXBuildFile section */
03FC29A292ACC40490383A1F /* Pods_Plugin.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B2A61DA5A1F2DD4F959604D /* Pods_Plugin.framework */; };
20C0B05DCFC8E3958A738AF2 /* Pods_PluginTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6753A823D3815DB436415E3 /* Pods_PluginTests.framework */; };
50ADFF92201F53D600D50D53 /* Plugin.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 50ADFF88201F53D600D50D53 /* Plugin.framework */; };
50ADFF97201F53D600D50D53 /* PluginTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50ADFF96201F53D600D50D53 /* PluginTests.swift */; };
50ADFF99201F53D600D50D53 /* Plugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ADFF8B201F53D600D50D53 /* Plugin.h */; settings = {ATTRIBUTES = (Public, ); }; };
50ADFFA42020D75100D50D53 /* Capacitor.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 50ADFFA52020D75100D50D53 /* Capacitor.framework */; };
50ADFFA82020EE4F00D50D53 /* Plugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 50ADFFA72020EE4F00D50D53 /* Plugin.m */; };
50E1A94820377CB70090CE1A /* Plugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50E1A94720377CB70090CE1A /* Plugin.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
50ADFF93201F53D600D50D53 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 50ADFF7F201F53D600D50D53 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 50ADFF87201F53D600D50D53;
remoteInfo = Plugin;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
3B2A61DA5A1F2DD4F959604D /* Pods_Plugin.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Plugin.framework; sourceTree = BUILT_PRODUCTS_DIR; };
50ADFF88201F53D600D50D53 /* Plugin.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Plugin.framework; sourceTree = BUILT_PRODUCTS_DIR; };
50ADFF8B201F53D600D50D53 /* Plugin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Plugin.h; sourceTree = "<group>"; };
50ADFF8C201F53D600D50D53 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
50ADFF91201F53D600D50D53 /* PluginTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PluginTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
50ADFF96201F53D600D50D53 /* PluginTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PluginTests.swift; sourceTree = "<group>"; };
50ADFF98201F53D600D50D53 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
50ADFFA52020D75100D50D53 /* Capacitor.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Capacitor.framework; sourceTree = BUILT_PRODUCTS_DIR; };
50ADFFA72020EE4F00D50D53 /* Plugin.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Plugin.m; sourceTree = "<group>"; };
50E1A94720377CB70090CE1A /* Plugin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Plugin.swift; sourceTree = "<group>"; };
5E23F77F099397094342571A /* Pods-Plugin.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Plugin.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Plugin/Pods-Plugin.debug.xcconfig"; sourceTree = "<group>"; };
91781294A431A2A7CC6EB714 /* Pods-Plugin.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Plugin.release.xcconfig"; path = "Pods/Target Support Files/Pods-Plugin/Pods-Plugin.release.xcconfig"; sourceTree = "<group>"; };
96ED1B6440D6672E406C8D19 /* Pods-PluginTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PluginTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests.debug.xcconfig"; sourceTree = "<group>"; };
F65BB2953ECE002E1EF3E424 /* Pods-PluginTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PluginTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests.release.xcconfig"; sourceTree = "<group>"; };
F6753A823D3815DB436415E3 /* Pods_PluginTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PluginTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
50ADFF84201F53D600D50D53 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
50ADFFA42020D75100D50D53 /* Capacitor.framework in Frameworks */,
03FC29A292ACC40490383A1F /* Pods_Plugin.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
50ADFF8E201F53D600D50D53 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
50ADFF92201F53D600D50D53 /* Plugin.framework in Frameworks */,
20C0B05DCFC8E3958A738AF2 /* Pods_PluginTests.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
50ADFF7E201F53D600D50D53 = {
isa = PBXGroup;
children = (
50ADFF8A201F53D600D50D53 /* Plugin */,
50ADFF95201F53D600D50D53 /* PluginTests */,
50ADFF89201F53D600D50D53 /* Products */,
8C8E7744173064A9F6D438E3 /* Pods */,
A797B9EFA3DCEFEA1FBB66A9 /* Frameworks */,
);
sourceTree = "<group>";
};
50ADFF89201F53D600D50D53 /* Products */ = {
isa = PBXGroup;
children = (
50ADFF88201F53D600D50D53 /* Plugin.framework */,
50ADFF91201F53D600D50D53 /* PluginTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
50ADFF8A201F53D600D50D53 /* Plugin */ = {
isa = PBXGroup;
children = (
50E1A94720377CB70090CE1A /* Plugin.swift */,
50ADFF8B201F53D600D50D53 /* Plugin.h */,
50ADFFA72020EE4F00D50D53 /* Plugin.m */,
50ADFF8C201F53D600D50D53 /* Info.plist */,
);
path = Plugin;
sourceTree = "<group>";
};
50ADFF95201F53D600D50D53 /* PluginTests */ = {
isa = PBXGroup;
children = (
50ADFF96201F53D600D50D53 /* PluginTests.swift */,
50ADFF98201F53D600D50D53 /* Info.plist */,
);
path = PluginTests;
sourceTree = "<group>";
};
8C8E7744173064A9F6D438E3 /* Pods */ = {
isa = PBXGroup;
children = (
5E23F77F099397094342571A /* Pods-Plugin.debug.xcconfig */,
91781294A431A2A7CC6EB714 /* Pods-Plugin.release.xcconfig */,
96ED1B6440D6672E406C8D19 /* Pods-PluginTests.debug.xcconfig */,
F65BB2953ECE002E1EF3E424 /* Pods-PluginTests.release.xcconfig */,
);
name = Pods;
sourceTree = "<group>";
};
A797B9EFA3DCEFEA1FBB66A9 /* Frameworks */ = {
isa = PBXGroup;
children = (
50ADFFA52020D75100D50D53 /* Capacitor.framework */,
3B2A61DA5A1F2DD4F959604D /* Pods_Plugin.framework */,
F6753A823D3815DB436415E3 /* Pods_PluginTests.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
50ADFF85201F53D600D50D53 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
50ADFF99201F53D600D50D53 /* Plugin.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
50ADFF87201F53D600D50D53 /* Plugin */ = {
isa = PBXNativeTarget;
buildConfigurationList = 50ADFF9C201F53D600D50D53 /* Build configuration list for PBXNativeTarget "Plugin" */;
buildPhases = (
AB5B3E54B4E897F32C2279DA /* [CP] Check Pods Manifest.lock */,
50ADFF83201F53D600D50D53 /* Sources */,
50ADFF84201F53D600D50D53 /* Frameworks */,
50ADFF85201F53D600D50D53 /* Headers */,
50ADFF86201F53D600D50D53 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = Plugin;
productName = Plugin;
productReference = 50ADFF88201F53D600D50D53 /* Plugin.framework */;
productType = "com.apple.product-type.framework";
};
50ADFF90201F53D600D50D53 /* PluginTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 50ADFF9F201F53D600D50D53 /* Build configuration list for PBXNativeTarget "PluginTests" */;
buildPhases = (
0596884F929ED6F1DE134961 /* [CP] Check Pods Manifest.lock */,
50ADFF8D201F53D600D50D53 /* Sources */,
50ADFF8E201F53D600D50D53 /* Frameworks */,
50ADFF8F201F53D600D50D53 /* Resources */,
CCA81D3B7E26D0D727D24C84 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
dependencies = (
50ADFF94201F53D600D50D53 /* PBXTargetDependency */,
);
name = PluginTests;
productName = PluginTests;
productReference = 50ADFF91201F53D600D50D53 /* PluginTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
50ADFF7F201F53D600D50D53 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0920;
LastUpgradeCheck = 0920;
ORGANIZATIONNAME = "Max Lynch";
TargetAttributes = {
50ADFF87201F53D600D50D53 = {
CreatedOnToolsVersion = 9.2;
LastSwiftMigration = 1100;
ProvisioningStyle = Automatic;
};
50ADFF90201F53D600D50D53 = {
CreatedOnToolsVersion = 9.2;
LastSwiftMigration = 1100;
ProvisioningStyle = Automatic;
};
};
};
buildConfigurationList = 50ADFF82201F53D600D50D53 /* Build configuration list for PBXProject "Plugin" */;
compatibilityVersion = "Xcode 8.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = 50ADFF7E201F53D600D50D53;
productRefGroup = 50ADFF89201F53D600D50D53 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
50ADFF87201F53D600D50D53 /* Plugin */,
50ADFF90201F53D600D50D53 /* PluginTests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
50ADFF86201F53D600D50D53 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
50ADFF8F201F53D600D50D53 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
0596884F929ED6F1DE134961 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-PluginTests-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
AB5B3E54B4E897F32C2279DA /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Plugin-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
CCA81D3B7E26D0D727D24C84 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-PluginTests/Pods-PluginTests-frameworks.sh",
"${BUILT_PRODUCTS_DIR}/Capacitor/Capacitor.framework",
"${BUILT_PRODUCTS_DIR}/CapacitorCordova/Cordova.framework",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Capacitor.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Cordova.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-PluginTests/Pods-PluginTests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
50ADFF83201F53D600D50D53 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
50E1A94820377CB70090CE1A /* Plugin.swift in Sources */,
50ADFFA82020EE4F00D50D53 /* Plugin.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
50ADFF8D201F53D600D50D53 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
50ADFF97201F53D600D50D53 /* PluginTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
50ADFF94201F53D600D50D53 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 50ADFF87201F53D600D50D53 /* Plugin */;
targetProxy = 50ADFF93201F53D600D50D53 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
50ADFF9A201F53D600D50D53 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
50ADFF9B201F53D600D50D53 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
50ADFF9D201F53D600D50D53 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 5E23F77F099397094342571A /* Pods-Plugin.debug.xcconfig */;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Automatic;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = Plugin/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks $(FRAMEWORK_SEARCH_PATHS)\n$(FRAMEWORK_SEARCH_PATHS)\n$(FRAMEWORK_SEARCH_PATHS)";
ONLY_ACTIVE_ARCH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.getcapacitor.Plugin;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
SUPPORTS_MACCATALYST = NO;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
50ADFF9E201F53D600D50D53 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 91781294A431A2A7CC6EB714 /* Pods-Plugin.release.xcconfig */;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Automatic;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = Plugin/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks $(FRAMEWORK_SEARCH_PATHS)";
ONLY_ACTIVE_ARCH = NO;
PRODUCT_BUNDLE_IDENTIFIER = com.getcapacitor.Plugin;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
SUPPORTS_MACCATALYST = NO;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
50ADFFA0201F53D600D50D53 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 96ED1B6440D6672E406C8D19 /* Pods-PluginTests.debug.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
INFOPLIST_FILE = PluginTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.getcapacitor.PluginTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
50ADFFA1201F53D600D50D53 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = F65BB2953ECE002E1EF3E424 /* Pods-PluginTests.release.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
INFOPLIST_FILE = PluginTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.getcapacitor.PluginTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
50ADFF82201F53D600D50D53 /* Build configuration list for PBXProject "Plugin" */ = {
isa = XCConfigurationList;
buildConfigurations = (
50ADFF9A201F53D600D50D53 /* Debug */,
50ADFF9B201F53D600D50D53 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
50ADFF9C201F53D600D50D53 /* Build configuration list for PBXNativeTarget "Plugin" */ = {
isa = XCConfigurationList;
buildConfigurations = (
50ADFF9D201F53D600D50D53 /* Debug */,
50ADFF9E201F53D600D50D53 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
50ADFF9F201F53D600D50D53 /* Build configuration list for PBXNativeTarget "PluginTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
50ADFFA0201F53D600D50D53 /* Debug */,
50ADFFA1201F53D600D50D53 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 50ADFF7F201F53D600D50D53 /* Project object */;
}

View File

@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Plugin.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>

View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@@ -1,42 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>NSMicrophoneUsageDescription</key>
<string>Privacy - Speech Recording for Transcription and audio visualization</string>
<key>LSApplicationCategoryType</key>
<string></string>
<key>NSSpeechRecognitionUsageDescription</key>
<string>Privacy - Microphone Usage Description</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>
<string></string>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<!-- Add this dict entry to the array if the PrivacyInfo file already exists -->
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>C617.1</string>
</array>
</dict>
</array>
</dict>
</plist>

View File

@@ -1,10 +0,0 @@
#import <UIKit/UIKit.h>
//! Project version number for Plugin.
FOUNDATION_EXPORT double PluginVersionNumber;
//! Project version string for Plugin.
FOUNDATION_EXPORT const unsigned char PluginVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <Plugin/PublicHeader.h>

View File

@@ -1,21 +0,0 @@
#import <Foundation/Foundation.h>
#import <Capacitor/Capacitor.h>
// Define the plugin using the CAP_PLUGIN Macro, and
// each method the plugin supports using the CAP_PLUGIN_METHOD macro.
CAP_PLUGIN(SpeechRecognition, "SpeechRecognition",
CAP_PLUGIN_METHOD(available, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(record, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(stopRecording, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(startMicrophoneStream, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(stopMicrophoneStream, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(start, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(stop, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(getSupportedLanguages, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(hasPermission, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(isListening, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(requestPermission, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(checkPermissions, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(requestPermissions, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(removeAllListeners, CAPPluginReturnPromise);
)

View File

@@ -1,324 +0,0 @@
import Capacitor
import Foundation
import Speech
extension AVAudioPCMBuffer {
func toArray() -> [Float] {
let ptr = self.floatChannelData?[0]
let buf = UnsafeBufferPointer(start: ptr, count: Int(self.frameLength))
return Array(buf)
}
}
@objc(SpeechRecognition)
public class SpeechRecognition: CAPPlugin {
let defaultMatches = 5
let messageMissingPermission = "Missing permission"
let messageAccessDenied = "User denied access to speech recognition"
let messageRestricted = "Speech recognition restricted on this device"
let messageNotDetermined = "Speech recognition not determined on this device"
let messageAccessDeniedMicrophone = "User denied access to microphone"
let messageOngoing = "Ongoing speech recognition"
let messageUnknown = "Unknown error occured"
private var speechRecognizer: SFSpeechRecognizer?
private var audioEngine: AVAudioEngine?
private var recognitionRequest: SFSpeechAudioBufferRecognitionRequest?
private var recognitionTask: SFSpeechRecognitionTask?
private var audioRecorder: AVAudioRecorder?
private var microphoneNode: AVAudioInputNode?
@objc func startMicrophoneStream(_ call: CAPPluginCall) {
let audioSession = AVAudioSession.sharedInstance()
do {
try audioSession.setCategory(.playAndRecord, options: .defaultToSpeaker)
try audioSession.setActive(true)
if audioEngine == nil {
audioEngine = AVAudioEngine()
}
guard let audioEngine = audioEngine else {
call.reject("Failed to create audio engine")
return
}
microphoneNode = audioEngine.inputNode
let format = microphoneNode?.outputFormat(forBus: 0)
// Install tap on microphone node to get real-time audio data
microphoneNode?.installTap(onBus: 0, bufferSize: 1024, format: format) {
(buffer, time) in
// Send audio buffer data to JavaScript
let data = ["buffer": buffer.toArray()]
self.notifyListeners("audioData", data: data)
}
try audioEngine.start()
call.resolve()
} catch {
call.reject("Failed to start microphone: \(error.localizedDescription)")
}
}
@objc func stopMicrophoneStream(_ call: CAPPluginCall) {
if let node = microphoneNode {
node.removeTap(onBus: 0)
}
audioEngine?.stop()
microphoneNode = nil
call.resolve()
}
@objc func record(_ call: CAPPluginCall) {
let audioSession = AVAudioSession.sharedInstance()
do {
try audioSession.setCategory(.playAndRecord, options: .defaultToSpeaker)
try audioSession.setActive(true)
// Use Documents directory
let documentsPath = FileManager.default.urls(
for: .documentDirectory, in: .userDomainMask)[0]
let fileName = call.getString("fileName") ?? "recording.wav"
let audioFilename = documentsPath.appendingPathComponent(fileName)
// Create parent directory if it doesn't exist
try FileManager.default.createDirectory(
at: documentsPath, withIntermediateDirectories: true)
let settings: [String: Any] = [
AVFormatIDKey: Int(kAudioFormatLinearPCM),
AVSampleRateKey: 44100.0,
AVNumberOfChannelsKey: 1,
AVLinearPCMBitDepthKey: 16,
AVLinearPCMIsFloatKey: false,
AVLinearPCMIsBigEndianKey: false,
AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue,
]
// Log the file path for debugging
print("Recording to path: \(audioFilename.path)")
// Create and start the audio recorder
audioRecorder = try AVAudioRecorder(url: audioFilename, settings: settings)
audioRecorder?.record()
// Return the file path to the caller
call.resolve([
"path": audioFilename.path
])
} catch {
call.reject("Failed to start recording: \(error.localizedDescription)")
}
}
@objc func stopRecording(_ call: CAPPluginCall) {
guard let recorder = audioRecorder, recorder.isRecording else {
call.reject("No active recording")
return
}
recorder.stop()
audioRecorder = nil
call.resolve()
}
@objc func available(_ call: CAPPluginCall) {
guard let recognizer = SFSpeechRecognizer() else {
call.resolve([
"available": false
])
return
}
call.resolve([
"available": recognizer.isAvailable
])
}
@objc func start(_ call: CAPPluginCall) {
if self.audioEngine != nil {
if self.audioEngine!.isRunning {
call.reject(self.messageOngoing)
return
}
}
let status: SFSpeechRecognizerAuthorizationStatus = SFSpeechRecognizer.authorizationStatus()
if status != SFSpeechRecognizerAuthorizationStatus.authorized {
call.reject(self.messageMissingPermission)
return
}
AVAudioSession.sharedInstance().requestRecordPermission { (granted) in
if !granted {
call.reject(self.messageAccessDeniedMicrophone)
return
}
let language: String = call.getString("language") ?? "en-US"
let maxResults: Int = call.getInt("maxResults") ?? self.defaultMatches
let partialResults: Bool = call.getBool("partialResults") ?? false
if self.recognitionTask != nil {
self.recognitionTask?.cancel()
self.recognitionTask = nil
}
self.audioEngine = AVAudioEngine.init()
self.speechRecognizer = SFSpeechRecognizer.init(locale: Locale(identifier: language))
let audioSession: AVAudioSession = AVAudioSession.sharedInstance()
do {
try audioSession.setCategory(
AVAudioSession.Category.playAndRecord,
options: AVAudioSession.CategoryOptions.defaultToSpeaker)
try audioSession.setMode(AVAudioSession.Mode.default)
try audioSession.setActive(
true, options: AVAudioSession.SetActiveOptions.notifyOthersOnDeactivation)
} catch {
}
self.recognitionRequest = SFSpeechAudioBufferRecognitionRequest()
self.recognitionRequest?.shouldReportPartialResults = partialResults
let inputNode: AVAudioInputNode = self.audioEngine!.inputNode
let format: AVAudioFormat = inputNode.outputFormat(forBus: 0)
self.recognitionTask = self.speechRecognizer?.recognitionTask(
with: self.recognitionRequest!,
resultHandler: { (result, error) in
if result != nil {
let resultArray: NSMutableArray = NSMutableArray()
var counter: Int = 0
for transcription: SFTranscription in result!.transcriptions {
if maxResults > 0 && counter < maxResults {
resultArray.add(transcription.formattedString)
}
counter += 1
}
if partialResults {
self.notifyListeners("partialResults", data: ["matches": resultArray])
} else {
call.resolve([
"matches": resultArray
])
}
if result!.isFinal {
self.audioEngine!.stop()
self.audioEngine?.inputNode.removeTap(onBus: 0)
self.notifyListeners("listeningState", data: ["status": "stopped"])
self.recognitionTask = nil
self.recognitionRequest = nil
}
}
if error != nil {
self.audioEngine!.stop()
self.audioEngine?.inputNode.removeTap(onBus: 0)
self.recognitionRequest = nil
self.recognitionTask = nil
self.notifyListeners("listeningState", data: ["status": "stopped"])
call.reject(error!.localizedDescription)
}
})
inputNode.installTap(onBus: 0, bufferSize: 1024, format: format) {
(buffer: AVAudioPCMBuffer, _: AVAudioTime) in
self.recognitionRequest?.append(buffer)
}
self.audioEngine?.prepare()
do {
try self.audioEngine?.start()
self.notifyListeners("listeningState", data: ["status": "started"])
if partialResults {
call.resolve()
}
} catch {
call.reject(self.messageUnknown)
}
}
}
@objc func stop(_ call: CAPPluginCall) {
DispatchQueue.global(qos: DispatchQoS.QoSClass.default).async {
if let engine = self.audioEngine, engine.isRunning {
engine.stop()
self.recognitionRequest?.endAudio()
self.notifyListeners("listeningState", data: ["status": "stopped"])
}
call.resolve()
}
}
@objc func isListening(_ call: CAPPluginCall) {
let isListening = self.audioEngine?.isRunning ?? false
call.resolve([
"listening": isListening
])
}
@objc func getSupportedLanguages(_ call: CAPPluginCall) {
let supportedLanguages: Set<Locale>! = SFSpeechRecognizer.supportedLocales() as Set<Locale>
let languagesArr: NSMutableArray = NSMutableArray()
for lang: Locale in supportedLanguages {
languagesArr.add(lang.identifier)
}
call.resolve([
"languages": languagesArr
])
}
@objc override public func checkPermissions(_ call: CAPPluginCall) {
let status: SFSpeechRecognizerAuthorizationStatus = SFSpeechRecognizer.authorizationStatus()
let permission: String
switch status {
case .authorized:
permission = "granted"
case .denied, .restricted:
permission = "denied"
case .notDetermined:
permission = "prompt"
@unknown default:
permission = "prompt"
}
call.resolve(["speechRecognition": permission])
}
@objc override public func requestPermissions(_ call: CAPPluginCall) {
SFSpeechRecognizer.requestAuthorization { (status: SFSpeechRecognizerAuthorizationStatus) in
DispatchQueue.main.async {
switch status {
case .authorized:
AVAudioSession.sharedInstance().requestRecordPermission { (granted: Bool) in
if granted {
call.resolve(["speechRecognition": "granted"])
} else {
call.resolve(["speechRecognition": "denied"])
}
}
break
case .denied, .restricted, .notDetermined:
self.checkPermissions(call)
break
@unknown default:
self.checkPermissions(call)
}
}
}
}
}

View File

@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>

View File

@@ -1,25 +0,0 @@
import XCTest
import Capacitor
@testable import Plugin
class PluginTests: XCTestCase {
func testEcho() {
// This is an example of a functional test case for a plugin.
// Use XCTAssert and related functions to verify your tests produce the correct results.
let value = "Hello, World!"
let plugin = MyPlugin()
let call = CAPPluginCall(callbackId: "test", options: [
"value": value
], resolve: { (result, _) in
let resultValue = result!.data["value"] as? String
XCTAssertEqual(value, resultValue)
}, reject: { (_) in
XCTFail("Error shouldn't have been called")
})
plugin.echo(call!)
}
}

View File

@@ -1,16 +0,0 @@
platform :ios, '13.0'
def capacitor_pods
# Comment the next line if you're not using Swift and don't want to use dynamic frameworks
use_frameworks!
pod 'Capacitor', :path => '../node_modules/@capacitor/ios'
pod 'CapacitorCordova', :path => '../node_modules/@capacitor/ios'
end
target 'Plugin' do
capacitor_pods
end
target 'PluginTests' do
capacitor_pods
end

View File

@@ -1,22 +0,0 @@
PODS:
- Capacitor (6.0.0):
- CapacitorCordova
- CapacitorCordova (6.0.0)
DEPENDENCIES:
- "Capacitor (from `../node_modules/@capacitor/ios`)"
- "CapacitorCordova (from `../node_modules/@capacitor/ios`)"
EXTERNAL SOURCES:
Capacitor:
:path: "../node_modules/@capacitor/ios"
CapacitorCordova:
:path: "../node_modules/@capacitor/ios"
SPEC CHECKSUMS:
Capacitor: 559d073c4ca6c27f8e7002c807eea94c3ba435a9
CapacitorCordova: 8c4bfdf69368512e85b1d8b724dd7546abeb30af
PODFILE CHECKSUM: 1033dea949db4aa66cc0404a8baadac4a30dd025
COCOAPODS: 1.16.2

View File

@@ -1,31 +0,0 @@
{
"name": "Capacitor",
"version": "6.0.0",
"summary": "Capacitor for iOS",
"social_media_url": "https://twitter.com/capacitorjs",
"license": "MIT",
"homepage": "https://capacitorjs.com/",
"platforms": {
"ios": "13.0"
},
"authors": {
"Ionic Team": "hi@ionicframework.com"
},
"source": {
"git": "https://github.com/ionic-team/capacitor.git",
"tag": "6.0.0"
},
"source_files": "Capacitor/Capacitor/**/*.{swift,h,m}",
"module_map": "Capacitor/Capacitor/Capacitor.modulemap",
"resources": [
"Capacitor/Capacitor/assets/native-bridge.js",
"Capacitor/Capacitor/PrivacyInfo.xcprivacy"
],
"dependencies": {
"CapacitorCordova": [
]
},
"swift_versions": "5.1",
"swift_version": "5.1"
}

View File

@@ -1,29 +0,0 @@
{
"name": "CapacitorCordova",
"module_name": "Cordova",
"version": "6.0.0",
"summary": "Capacitor Cordova Compatibility Layer",
"homepage": "https://capacitorjs.com",
"license": "MIT",
"authors": {
"Ionic Team": "hi@ionicframework.com"
},
"source": {
"git": "https://github.com/ionic-team/capacitor",
"tag": "6.0.0"
},
"platforms": {
"ios": "13.0"
},
"source_files": "CapacitorCordova/CapacitorCordova/**/*.{h,m}",
"public_header_files": [
"CapacitorCordova/CapacitorCordova/Classes/Public/*.h",
"CapacitorCordova/CapacitorCordova/CapacitorCordova.h"
],
"module_map": "CapacitorCordova/CapacitorCordova/CapacitorCordova.modulemap",
"resources": [
"CapacitorCordova/CapacitorCordova/PrivacyInfo.xcprivacy"
],
"requires_arc": true,
"frameworks": "WebKit"
}

View File

@@ -1,22 +0,0 @@
PODS:
- Capacitor (6.0.0):
- CapacitorCordova
- CapacitorCordova (6.0.0)
DEPENDENCIES:
- "Capacitor (from `../node_modules/@capacitor/ios`)"
- "CapacitorCordova (from `../node_modules/@capacitor/ios`)"
EXTERNAL SOURCES:
Capacitor:
:path: "../node_modules/@capacitor/ios"
CapacitorCordova:
:path: "../node_modules/@capacitor/ios"
SPEC CHECKSUMS:
Capacitor: 559d073c4ca6c27f8e7002c807eea94c3ba435a9
CapacitorCordova: 8c4bfdf69368512e85b1d8b724dd7546abeb30af
PODFILE CHECKSUM: 1033dea949db4aa66cc0404a8baadac4a30dd025
COCOAPODS: 1.16.2

File diff suppressed because it is too large Load Diff

View File

@@ -1,58 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1600"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0ECF3D6BFCC08377AE23B027EE1D4371"
BuildableName = "Capacitor.framework"
BlueprintName = "Capacitor"
ReferencedContainer = "container:Pods.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -1,58 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1600"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "400AE44335852A2D8D746557E21E8EB0"
BuildableName = "Cordova.framework"
BlueprintName = "CapacitorCordova"
ReferencedContainer = "container:Pods.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -1,58 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1600"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "10467BF5021453A5297325418ACC4E64"
BuildableName = "Pods_Plugin.framework"
BlueprintName = "Pods-Plugin"
ReferencedContainer = "container:Pods.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -1,58 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1600"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "401C34F4B17A319A7086C93431C92B42"
BuildableName = "Pods_PluginTests.framework"
BlueprintName = "Pods-PluginTests"
ReferencedContainer = "container:Pods.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -1,31 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>Capacitor.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
</dict>
<key>CapacitorCordova.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
</dict>
<key>Pods-Plugin.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
</dict>
<key>Pods-PluginTests.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict/>
</dict>
</plist>

View File

@@ -1,26 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>${PODS_DEVELOPMENT_LANGUAGE}</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>6.0.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${CURRENT_PROJECT_VERSION}</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>

View File

@@ -1,5 +0,0 @@
#import <Foundation/Foundation.h>
@interface PodsDummy_Capacitor : NSObject
@end
@implementation PodsDummy_Capacitor
@end

View File

@@ -1,12 +0,0 @@
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif

View File

@@ -1,16 +0,0 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Capacitor
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CapacitorCordova"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
OTHER_LDFLAGS = $(inherited) -framework "Cordova" -framework "WebKit"
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/../../node_modules/@capacitor/ios
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES

View File

@@ -1,8 +0,0 @@
framework module Capacitor {
umbrella header "Capacitor.h"
exclude header "CAPBridgedJSTypes.h"
exclude header "CAPBridgeViewController+CDVScreenOrientationDelegate.h"
export *
module * { export * }
}

View File

@@ -1,16 +0,0 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Capacitor
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CapacitorCordova"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
OTHER_LDFLAGS = $(inherited) -framework "Cordova" -framework "WebKit"
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/../../node_modules/@capacitor/ios
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES

View File

@@ -1,26 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>${PODS_DEVELOPMENT_LANGUAGE}</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>6.0.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${CURRENT_PROJECT_VERSION}</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>

View File

@@ -1,5 +0,0 @@
#import <Foundation/Foundation.h>
@interface PodsDummy_CapacitorCordova : NSObject
@end
@implementation PodsDummy_CapacitorCordova
@end

View File

@@ -1,12 +0,0 @@
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif

View File

@@ -1,13 +0,0 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CapacitorCordova
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
OTHER_LDFLAGS = $(inherited) -framework "WebKit"
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/../../node_modules/@capacitor/ios
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES

View File

@@ -1,6 +0,0 @@
framework module Cordova {
umbrella header "CapacitorCordova.h"
export *
module * { export * }
}

View File

@@ -1,13 +0,0 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CapacitorCordova
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
OTHER_LDFLAGS = $(inherited) -framework "WebKit"
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/../../node_modules/@capacitor/ios
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES

View File

@@ -1,26 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>${PODS_DEVELOPMENT_LANGUAGE}</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${CURRENT_PROJECT_VERSION}</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>

View File

@@ -1,53 +0,0 @@
# Acknowledgements
This application makes use of the following third party libraries:
## Capacitor
MIT License
Copyright (c) 2017-present Drifty Co.
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.
## CapacitorCordova
MIT License
Copyright (c) 2017-present Drifty Co.
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.
Generated by CocoaPods - https://cocoapods.org

View File

@@ -1,91 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreferenceSpecifiers</key>
<array>
<dict>
<key>FooterText</key>
<string>This application makes use of the following third party libraries:</string>
<key>Title</key>
<string>Acknowledgements</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict>
<key>FooterText</key>
<string>MIT License
Copyright (c) 2017-present Drifty Co.
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.
</string>
<key>License</key>
<string>MIT</string>
<key>Title</key>
<string>Capacitor</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict>
<key>FooterText</key>
<string>MIT License
Copyright (c) 2017-present Drifty Co.
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.
</string>
<key>License</key>
<string>MIT</string>
<key>Title</key>
<string>CapacitorCordova</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict>
<key>FooterText</key>
<string>Generated by CocoaPods - https://cocoapods.org</string>
<key>Title</key>
<string></string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
</array>
<key>StringsTable</key>
<string>Acknowledgements</string>
<key>Title</key>
<string>Acknowledgements</string>
</dict>
</plist>

View File

@@ -1,5 +0,0 @@
#import <Foundation/Foundation.h>
@interface PodsDummy_Pods_Plugin : NSObject
@end
@implementation PodsDummy_Pods_Plugin
@end

View File

@@ -1,16 +0,0 @@
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif
FOUNDATION_EXPORT double Pods_PluginVersionNumber;
FOUNDATION_EXPORT const unsigned char Pods_PluginVersionString[];

View File

@@ -1,15 +0,0 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Capacitor" "${PODS_CONFIGURATION_BUILD_DIR}/CapacitorCordova"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Capacitor/Capacitor.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CapacitorCordova/Cordova.framework/Headers"
LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' '@executable_path/../../Frameworks'
LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
OTHER_LDFLAGS = $(inherited) -framework "Capacitor" -framework "Cordova" -framework "WebKit"
OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/Capacitor" "-F${PODS_CONFIGURATION_BUILD_DIR}/CapacitorCordova"
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
PODS_ROOT = ${SRCROOT}/Pods
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES

View File

@@ -1,6 +0,0 @@
framework module Pods_Plugin {
umbrella header "Pods-Plugin-umbrella.h"
export *
module * { export * }
}

View File

@@ -1,15 +0,0 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Capacitor" "${PODS_CONFIGURATION_BUILD_DIR}/CapacitorCordova"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Capacitor/Capacitor.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CapacitorCordova/Cordova.framework/Headers"
LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' '@executable_path/../../Frameworks'
LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
OTHER_LDFLAGS = $(inherited) -framework "Capacitor" -framework "Cordova" -framework "WebKit"
OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/Capacitor" "-F${PODS_CONFIGURATION_BUILD_DIR}/CapacitorCordova"
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
PODS_ROOT = ${SRCROOT}/Pods
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES

View File

@@ -1,26 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>${PODS_DEVELOPMENT_LANGUAGE}</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${CURRENT_PROJECT_VERSION}</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>

View File

@@ -1,53 +0,0 @@
# Acknowledgements
This application makes use of the following third party libraries:
## Capacitor
MIT License
Copyright (c) 2017-present Drifty Co.
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.
## CapacitorCordova
MIT License
Copyright (c) 2017-present Drifty Co.
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.
Generated by CocoaPods - https://cocoapods.org

View File

@@ -1,91 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreferenceSpecifiers</key>
<array>
<dict>
<key>FooterText</key>
<string>This application makes use of the following third party libraries:</string>
<key>Title</key>
<string>Acknowledgements</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict>
<key>FooterText</key>
<string>MIT License
Copyright (c) 2017-present Drifty Co.
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.
</string>
<key>License</key>
<string>MIT</string>
<key>Title</key>
<string>Capacitor</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict>
<key>FooterText</key>
<string>MIT License
Copyright (c) 2017-present Drifty Co.
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.
</string>
<key>License</key>
<string>MIT</string>
<key>Title</key>
<string>CapacitorCordova</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict>
<key>FooterText</key>
<string>Generated by CocoaPods - https://cocoapods.org</string>
<key>Title</key>
<string></string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
</array>
<key>StringsTable</key>
<string>Acknowledgements</string>
<key>Title</key>
<string>Acknowledgements</string>
</dict>
</plist>

Some files were not shown because too many files have changed in this diff Show More