react-native-waveform-player 0.0.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AudioWaveform.podspec +29 -0
- package/LICENSE +20 -0
- package/README.md +296 -0
- package/android/build.gradle +67 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/java/com/audiowaveform/AudioPlayerEngine.kt +353 -0
- package/android/src/main/java/com/audiowaveform/AudioWaveformEvent.kt +22 -0
- package/android/src/main/java/com/audiowaveform/AudioWaveformPackage.kt +17 -0
- package/android/src/main/java/com/audiowaveform/AudioWaveformView.kt +715 -0
- package/android/src/main/java/com/audiowaveform/AudioWaveformViewManager.kt +234 -0
- package/android/src/main/java/com/audiowaveform/PlayPauseButton.kt +106 -0
- package/android/src/main/java/com/audiowaveform/SpeedPillView.kt +70 -0
- package/android/src/main/java/com/audiowaveform/WaveformBarsView.kt +358 -0
- package/android/src/main/java/com/audiowaveform/WaveformDecoder.kt +240 -0
- package/android/src/main/res/drawable/pause_fill.xml +15 -0
- package/android/src/main/res/drawable/play_fill.xml +15 -0
- package/ios/AudioPlayerEngine.swift +281 -0
- package/ios/AudioWaveformView.h +14 -0
- package/ios/AudioWaveformView.mm +307 -0
- package/ios/AudioWaveformViewImpl.swift +835 -0
- package/ios/PlayPauseButton.swift +118 -0
- package/ios/SpeedPillView.swift +70 -0
- package/ios/WaveformBarsView.swift +327 -0
- package/ios/WaveformDecoder.swift +332 -0
- package/lib/module/AudioWaveformView.js +8 -0
- package/lib/module/AudioWaveformView.js.map +1 -0
- package/lib/module/AudioWaveformView.native.js +79 -0
- package/lib/module/AudioWaveformView.native.js.map +1 -0
- package/lib/module/AudioWaveformViewNativeComponent.ts +95 -0
- package/lib/module/index.js +4 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/AudioWaveformView.d.ts +233 -0
- package/lib/typescript/src/AudioWaveformView.d.ts.map +1 -0
- package/lib/typescript/src/AudioWaveformView.native.d.ts +335 -0
- package/lib/typescript/src/AudioWaveformView.native.d.ts.map +1 -0
- package/lib/typescript/src/AudioWaveformViewNativeComponent.d.ts +71 -0
- package/lib/typescript/src/AudioWaveformViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +3 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/package.json +138 -7
- package/src/AudioWaveformView.native.tsx +281 -0
- package/src/AudioWaveformView.tsx +96 -0
- package/src/AudioWaveformViewNativeComponent.ts +95 -0
- package/src/index.tsx +13 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
|
|
3
|
+
package = JSON.parse(File.read(File.join(__dir__, "package.json")))
|
|
4
|
+
|
|
5
|
+
Pod::Spec.new do |s|
|
|
6
|
+
s.name = "AudioWaveform"
|
|
7
|
+
s.version = package["version"]
|
|
8
|
+
s.summary = package["description"]
|
|
9
|
+
s.homepage = package["homepage"]
|
|
10
|
+
s.license = package["license"]
|
|
11
|
+
s.authors = package["author"]
|
|
12
|
+
|
|
13
|
+
s.platforms = { :ios => min_ios_version_supported }
|
|
14
|
+
s.source = { :git => "https://github.com/maitrungduc1410/react-native-audio-waveform.git", :tag => "#{s.version}" }
|
|
15
|
+
|
|
16
|
+
s.source_files = "ios/**/*.{h,m,mm,swift,cpp}"
|
|
17
|
+
s.private_header_files = "ios/**/*.h"
|
|
18
|
+
|
|
19
|
+
s.swift_versions = ["5.0"]
|
|
20
|
+
s.frameworks = "AVFoundation", "CoreMedia", "QuartzCore", "UIKit"
|
|
21
|
+
|
|
22
|
+
s.pod_target_xcconfig = {
|
|
23
|
+
"DEFINES_MODULE" => "YES",
|
|
24
|
+
"SWIFT_OBJC_INTERFACE_HEADER_NAME" => "AudioWaveform-Swift.h",
|
|
25
|
+
"CLANG_CXX_LANGUAGE_STANDARD" => "c++20"
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
install_modules_dependencies(s)
|
|
29
|
+
end
|
package/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Duc Trung Mai
|
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
in the Software without restriction, including without limitation the rights
|
|
7
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
furnished to do so, subject to the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
# react-native-waveform-player
|
|
2
|
+
|
|
3
|
+
Native audio-message UI for React Native — play any local or remote audio file
|
|
4
|
+
and render its waveform purely natively. Swift on iOS, Kotlin on Android,
|
|
5
|
+
Fabric (new architecture) only.
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<img src="./demo/ios.png" alt="iOS" width="48%" />
|
|
9
|
+
<img src="./demo/android.png" alt="Android" width="48%" />
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
## Features
|
|
13
|
+
|
|
14
|
+
- Play / pause / scrub / cycle speed — all rendered in native code, no JS in
|
|
15
|
+
the hot path.
|
|
16
|
+
- Custom rounded-bar waveform with a partial-fill playhead (the bar straddling
|
|
17
|
+
the playhead is highlighted up to the exact pixel).
|
|
18
|
+
- Press-and-drag scrubbing with zero activation delay.
|
|
19
|
+
- Configurable bar size / gap / radius / count, played + unplayed colors.
|
|
20
|
+
- Built-in play button, time label (count-up or count-down), and tap-to-cycle
|
|
21
|
+
speed pill — each individually showable / themable.
|
|
22
|
+
- Pre-computed `samples` escape hatch when you already have peaks data.
|
|
23
|
+
- Controlled (`playing`, `speed`) and uncontrolled modes.
|
|
24
|
+
- Imperative `ref.play()` / `pause()` / `toggle()` / `seekTo(ms)` /
|
|
25
|
+
`setSpeed(s)`.
|
|
26
|
+
- Opt-in background playback via `playInBackground` (paused on backgrounding
|
|
27
|
+
by default), with `pauseUiUpdatesInBackground` to skip cheap-but-pointless
|
|
28
|
+
UI work while offscreen.
|
|
29
|
+
- Events: `onLoad`, `onLoadError`, `onPlayerStateChange`, `onTimeUpdate`,
|
|
30
|
+
`onSeek`, `onEnd`.
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
```sh
|
|
35
|
+
npm install react-native-waveform-player
|
|
36
|
+
# or
|
|
37
|
+
yarn add react-native-waveform-player
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
iOS:
|
|
41
|
+
|
|
42
|
+
```sh
|
|
43
|
+
cd ios && pod install
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
This library is Fabric-only; the host app must have the new architecture
|
|
47
|
+
enabled (it's the default in RN 0.85+).
|
|
48
|
+
|
|
49
|
+
## Usage
|
|
50
|
+
|
|
51
|
+
```tsx
|
|
52
|
+
import { AudioWaveformView } from 'react-native-waveform-player';
|
|
53
|
+
|
|
54
|
+
export function VoiceNote() {
|
|
55
|
+
return (
|
|
56
|
+
<AudioWaveformView
|
|
57
|
+
source={{
|
|
58
|
+
uri: 'https://example.com/voice-note.m4a',
|
|
59
|
+
}}
|
|
60
|
+
style={{ height: 56 }}
|
|
61
|
+
/>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Themed + count-down + custom speeds
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
<AudioWaveformView
|
|
70
|
+
source={{ uri: REMOTE_AUDIO }}
|
|
71
|
+
containerBackgroundColor="#0F172A"
|
|
72
|
+
containerBorderRadius={20}
|
|
73
|
+
playedBarColor="#22D3EE"
|
|
74
|
+
unplayedBarColor="rgba(34, 211, 238, 0.35)"
|
|
75
|
+
playButtonColor="#22D3EE"
|
|
76
|
+
timeColor="#A5F3FC"
|
|
77
|
+
timeMode="count-down"
|
|
78
|
+
speedColor="#0F172A"
|
|
79
|
+
speedBackgroundColor="#22D3EE"
|
|
80
|
+
speeds={[1, 1.5, 2]}
|
|
81
|
+
defaultSpeed={1.5}
|
|
82
|
+
barWidth={4}
|
|
83
|
+
barGap={3}
|
|
84
|
+
style={{ height: 56 }}
|
|
85
|
+
/>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Controlled component
|
|
89
|
+
|
|
90
|
+
When `playing` and/or `speed` are supplied, the component is fully controlled
|
|
91
|
+
— tapping the play button or speed pill fires `onPlayerStateChange` with the
|
|
92
|
+
*requested* new value but does **not** mutate internal state. Update the prop
|
|
93
|
+
in your parent state.
|
|
94
|
+
|
|
95
|
+
```tsx
|
|
96
|
+
const [playing, setPlaying] = useState(false);
|
|
97
|
+
const [speed, setSpeed] = useState(1);
|
|
98
|
+
|
|
99
|
+
<AudioWaveformView
|
|
100
|
+
source={{ uri }}
|
|
101
|
+
playing={playing}
|
|
102
|
+
speed={speed}
|
|
103
|
+
onPlayerStateChange={(e) => {
|
|
104
|
+
if (e.isPlaying !== playing) setPlaying(e.isPlaying);
|
|
105
|
+
if (e.speed !== speed) setSpeed(e.speed);
|
|
106
|
+
}}
|
|
107
|
+
/>;
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Imperative ref API
|
|
111
|
+
|
|
112
|
+
```tsx
|
|
113
|
+
import {
|
|
114
|
+
AudioWaveformView,
|
|
115
|
+
type AudioWaveformViewRef,
|
|
116
|
+
} from 'react-native-waveform-player';
|
|
117
|
+
|
|
118
|
+
const ref = useRef<AudioWaveformViewRef>(null);
|
|
119
|
+
|
|
120
|
+
ref.current?.play();
|
|
121
|
+
ref.current?.pause();
|
|
122
|
+
ref.current?.toggle();
|
|
123
|
+
ref.current?.seekTo(0);
|
|
124
|
+
ref.current?.setSpeed(2);
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Pre-computed samples (skip native decode)
|
|
128
|
+
|
|
129
|
+
```tsx
|
|
130
|
+
<AudioWaveformView
|
|
131
|
+
source={{ uri }}
|
|
132
|
+
samples={[0.1, 0.4, 0.85, 0.6, /* ... */]}
|
|
133
|
+
/>
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Hide every chrome element (visualiser only)
|
|
137
|
+
|
|
138
|
+
```tsx
|
|
139
|
+
<AudioWaveformView
|
|
140
|
+
source={{ uri }}
|
|
141
|
+
showPlayButton={false}
|
|
142
|
+
showTime={false}
|
|
143
|
+
showSpeedControl={false}
|
|
144
|
+
showBackground={false}
|
|
145
|
+
/>
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Background playback
|
|
149
|
+
|
|
150
|
+
By default the component pauses playback when the host app is backgrounded
|
|
151
|
+
(matches iOS's default behaviour, and we add the same on Android for parity).
|
|
152
|
+
Opt in with `playInBackground`:
|
|
153
|
+
|
|
154
|
+
```tsx
|
|
155
|
+
<AudioWaveformView source={{ uri }} playInBackground />
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
When `playInBackground` is `true`:
|
|
159
|
+
|
|
160
|
+
#### iOS — required
|
|
161
|
+
|
|
162
|
+
Enable the **Audio** background mode on the host app target. Either:
|
|
163
|
+
|
|
164
|
+
1. **Xcode** → Project → app target → **Signing & Capabilities** →
|
|
165
|
+
**+ Capability** → **Background Modes** → check
|
|
166
|
+
*Audio, AirPlay, and Picture in Picture*.
|
|
167
|
+
|
|
168
|
+
_or_
|
|
169
|
+
|
|
170
|
+
2. Add to your app's `Info.plist`:
|
|
171
|
+
|
|
172
|
+
```xml
|
|
173
|
+
<key>UIBackgroundModes</key>
|
|
174
|
+
<array>
|
|
175
|
+
<string>audio</string>
|
|
176
|
+
</array>
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
The library configures `AVAudioSession` to `.playback` and activates it for
|
|
180
|
+
you. Note that this will play through the silent-mode switch and interrupt
|
|
181
|
+
other apps' audio (Spotify, etc.) by default. If your app already manages
|
|
182
|
+
its own audio session, set the category yourself before mounting the
|
|
183
|
+
component and the library won't override it.
|
|
184
|
+
|
|
185
|
+
#### Android — optional
|
|
186
|
+
|
|
187
|
+
`MediaPlayer` keeps playing through `Activity.onPause` already, so for
|
|
188
|
+
typical voice-message use cases **nothing extra is required**.
|
|
189
|
+
|
|
190
|
+
If you need playback to survive **device sleep** (screen off + idle, CPU
|
|
191
|
+
suspended), add `WAKE_LOCK` to your **app's** `AndroidManifest.xml`:
|
|
192
|
+
|
|
193
|
+
```xml
|
|
194
|
+
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
The library will then automatically call `MediaPlayer.setWakeMode` when
|
|
198
|
+
`playInBackground` is `true`. Without the permission `setWakeMode` is
|
|
199
|
+
silently skipped (a warning is logged) — playback still works while the
|
|
200
|
+
screen is on, it just pauses with the device.
|
|
201
|
+
|
|
202
|
+
#### Suspending UI work while backgrounded
|
|
203
|
+
|
|
204
|
+
The 30 Hz progress polling that drives the bars + time label keeps running
|
|
205
|
+
even after the OS has stopped compositing the view, so a tiny amount of
|
|
206
|
+
CPU is wasted on math + string formatting per tick.
|
|
207
|
+
|
|
208
|
+
`pauseUiUpdatesInBackground` (default `true`) gates that work:
|
|
209
|
+
|
|
210
|
+
- `true` — when backgrounded, skip the bars / time-label refreshes. The view
|
|
211
|
+
is offscreen so there's nothing visible to lose. The library snaps the UI
|
|
212
|
+
to the engine's current state on resume.
|
|
213
|
+
- `false` — keep refreshing in background (rare; only useful if something
|
|
214
|
+
in your view hierarchy is observing those UI changes from background).
|
|
215
|
+
|
|
216
|
+
`onTimeUpdate` keeps firing in either case, so Now Playing / Lock Screen /
|
|
217
|
+
analytics integrations work the same way.
|
|
218
|
+
|
|
219
|
+
## Props
|
|
220
|
+
|
|
221
|
+
| Prop | Type | Default | Description |
|
|
222
|
+
| -------------------------- | ----------------------------------- | ------------------------- | ----------- |
|
|
223
|
+
| `source` (required) | `{ uri: string }` | — | Audio source. Supports `file://`, `https://`, `content://`. |
|
|
224
|
+
| `samples` | `number[]` | `undefined` | Pre-computed amplitudes in `[0, 1]`. When set, native decode is skipped. |
|
|
225
|
+
| `playedBarColor` | `ColorValue` | `#FFFFFF` | Color of the highlighted ("played") portion of each bar. |
|
|
226
|
+
| `unplayedBarColor` | `ColorValue` | `rgba(255,255,255,0.5)` | Color of the not-yet-played portion. |
|
|
227
|
+
| `barWidth` | `number` | `3` | Bar thickness in dp. |
|
|
228
|
+
| `barGap` | `number` | `2` | Gap between bars in dp. |
|
|
229
|
+
| `barRadius` | `number` | `barWidth / 2` | Bar corner radius in dp. |
|
|
230
|
+
| `barCount` | `number` | auto from view width | Force a specific number of bars. |
|
|
231
|
+
| `containerBackgroundColor` | `ColorValue` | `#3478F6` | Rounded container background. |
|
|
232
|
+
| `containerBorderRadius` | `number` | `16` | Rounded container corner radius. |
|
|
233
|
+
| `showBackground` | `boolean` | `true` | Whether to draw the rounded container background. |
|
|
234
|
+
| `showPlayButton` | `boolean` | `true` | |
|
|
235
|
+
| `playButtonColor` | `ColorValue` | `#FFFFFF` | Play / pause icon tint (uses SF Symbols on iOS, vector drawables on Android). |
|
|
236
|
+
| `showTime` | `boolean` | `true` | |
|
|
237
|
+
| `timeColor` | `ColorValue` | `#FFFFFF` | |
|
|
238
|
+
| `timeMode` | `'count-up' \| 'count-down'` | `'count-up'` | |
|
|
239
|
+
| `showSpeedControl` | `boolean` | `true` | |
|
|
240
|
+
| `speedColor` | `ColorValue` | `#FFFFFF` | Speed pill text color. |
|
|
241
|
+
| `speedBackgroundColor` | `ColorValue` | `rgba(255,255,255,0.25)` | Speed pill background color. |
|
|
242
|
+
| `speeds` | `number[]` | `[0.5, 1, 1.5, 2]` | Tap-to-cycle speed values. |
|
|
243
|
+
| `defaultSpeed` | `number` | `1` | Initial speed on mount. |
|
|
244
|
+
| `autoPlay` | `boolean` | `false` | Begin playback as soon as the source is ready. |
|
|
245
|
+
| `initialPositionMs` | `number` | `0` | Seek to this position (ms) on load. |
|
|
246
|
+
| `loop` | `boolean` | `false` | Restart from `0` on end-of-track. |
|
|
247
|
+
| `playInBackground` | `boolean` | `false` | Keep playing when the host app backgrounds. iOS requires the Audio Background Mode; Android optionally honours `WAKE_LOCK`. See [Background playback](#background-playback). |
|
|
248
|
+
| `pauseUiUpdatesInBackground` | `boolean` | `true` | While backgrounded, suspend the bars / time-label refreshes that piggy-back on every progress tick. The OS already skips painting; this saves the cheap math/string work. `onTimeUpdate` is unaffected. |
|
|
249
|
+
| `playing` | `boolean \| undefined` | `undefined` | Controlled playing state. When defined, internal play/pause taps are inert. |
|
|
250
|
+
| `speed` | `number \| undefined` | `undefined` | Controlled speed. When defined, internal speed-pill taps are inert. |
|
|
251
|
+
|
|
252
|
+
### Events
|
|
253
|
+
|
|
254
|
+
| Event | Payload |
|
|
255
|
+
| ---------------------- | ---------------------------------------------------- |
|
|
256
|
+
| `onLoad` | `{ durationMs: number }` |
|
|
257
|
+
| `onLoadError` | `{ message: string }` |
|
|
258
|
+
| `onPlayerStateChange` | `{ state, isPlaying, speed, error? }` (full snapshot on every transition: load lifecycle, play/pause, speed change) |
|
|
259
|
+
| `onTimeUpdate` | `{ currentTimeMs, durationMs }` (≈30 Hz while playing) |
|
|
260
|
+
| `onSeek` | `{ positionMs }` (end of scrub gesture or `seekTo`) |
|
|
261
|
+
| `onEnd` | `{}` |
|
|
262
|
+
|
|
263
|
+
`state` is one of `'idle' | 'loading' | 'ready' | 'ended' | 'error'`.
|
|
264
|
+
|
|
265
|
+
### Imperative API
|
|
266
|
+
|
|
267
|
+
```ts
|
|
268
|
+
type AudioWaveformViewRef = {
|
|
269
|
+
play: () => void;
|
|
270
|
+
pause: () => void;
|
|
271
|
+
toggle: () => void;
|
|
272
|
+
seekTo: (positionMs: number) => void;
|
|
273
|
+
setSpeed: (speed: number) => void;
|
|
274
|
+
};
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
## Out of scope
|
|
278
|
+
|
|
279
|
+
- Recording (playback + visualisation only).
|
|
280
|
+
- Live / streaming waveforms — we visualise a fixed audio file.
|
|
281
|
+
- `react-native-gesture-handler` / Reanimated integration — gestures are
|
|
282
|
+
handled natively for zero JS overhead.
|
|
283
|
+
|
|
284
|
+
## Contributing
|
|
285
|
+
|
|
286
|
+
- [Development workflow](CONTRIBUTING.md#development-workflow)
|
|
287
|
+
- [Sending a pull request](CONTRIBUTING.md#sending-a-pull-request)
|
|
288
|
+
- [Code of conduct](CODE_OF_CONDUCT.md)
|
|
289
|
+
|
|
290
|
+
## License
|
|
291
|
+
|
|
292
|
+
MIT
|
|
293
|
+
|
|
294
|
+
---
|
|
295
|
+
|
|
296
|
+
Made with [create-react-native-library](https://github.com/callstack/react-native-builder-bob)
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
buildscript {
|
|
2
|
+
ext.AudioWaveform = [
|
|
3
|
+
kotlinVersion: "2.0.21",
|
|
4
|
+
minSdkVersion: 24,
|
|
5
|
+
compileSdkVersion: 36,
|
|
6
|
+
targetSdkVersion: 36
|
|
7
|
+
]
|
|
8
|
+
|
|
9
|
+
ext.getExtOrDefault = { prop ->
|
|
10
|
+
if (rootProject.ext.has(prop)) {
|
|
11
|
+
return rootProject.ext.get(prop)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return AudioWaveform[prop]
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
repositories {
|
|
18
|
+
google()
|
|
19
|
+
mavenCentral()
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
dependencies {
|
|
23
|
+
classpath "com.android.tools.build:gradle:8.7.2"
|
|
24
|
+
// noinspection DifferentKotlinGradleVersion
|
|
25
|
+
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${getExtOrDefault('kotlinVersion')}"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
apply plugin: "com.android.library"
|
|
31
|
+
apply plugin: "kotlin-android"
|
|
32
|
+
|
|
33
|
+
apply plugin: "com.facebook.react"
|
|
34
|
+
|
|
35
|
+
android {
|
|
36
|
+
namespace "com.audiowaveform"
|
|
37
|
+
|
|
38
|
+
compileSdkVersion getExtOrDefault("compileSdkVersion")
|
|
39
|
+
|
|
40
|
+
defaultConfig {
|
|
41
|
+
minSdkVersion getExtOrDefault("minSdkVersion")
|
|
42
|
+
targetSdkVersion getExtOrDefault("targetSdkVersion")
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
buildFeatures {
|
|
46
|
+
buildConfig true
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
buildTypes {
|
|
50
|
+
release {
|
|
51
|
+
minifyEnabled false
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
lint {
|
|
56
|
+
disable "GradleCompatible"
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
compileOptions {
|
|
60
|
+
sourceCompatibility JavaVersion.VERSION_1_8
|
|
61
|
+
targetCompatibility JavaVersion.VERSION_1_8
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
dependencies {
|
|
66
|
+
implementation "com.facebook.react:react-android"
|
|
67
|
+
}
|