fix(RN): bundle sound files in release build

On Android the files will be copied to the assets/sounds directory of
the SDK bundle on build time. To play the "asset:/" prefix has to be
used to locate the files correctly.

On iOS each sound file must be added to the SDK's Xcode project in order
to be bundled correctly. To playback we need to know the path of the SDK
bundle which is now exposed by the AppInfo iOS module.
This commit is contained in:
paweldomas 2018-04-05 14:12:24 -05:00 committed by Saúl Ibarra Corretgé
parent c377219013
commit 8b2ce21e1a
18 changed files with 103 additions and 51 deletions

View File

@ -71,6 +71,22 @@ gradle.projectsEvaluated {
runBefore("processUniversal${buildNameCapitalized}Resources", currentFontTask)
runBefore("process${buildNameCapitalized}Resources", currentFontTask)
def currentSoundsTask = tasks.create(
name: "copy${buildNameCapitalized}Sounds",
type: Copy) {
from("${projectDir}/../../sounds/joined.wav")
from("${projectDir}/../../sounds/left.wav")
into("${bundlePath}/assets/sounds")
}
currentSoundsTask.dependsOn("merge${buildNameCapitalized}Resources")
currentSoundsTask.dependsOn("merge${buildNameCapitalized}Assets")
runBefore("processArmeabi-v7a${buildNameCapitalized}Resources", currentSoundsTask)
runBefore("processX86${buildNameCapitalized}Resources", currentSoundsTask)
runBefore("processUniversal${buildNameCapitalized}Resources", currentSoundsTask)
runBefore("process${buildNameCapitalized}Resources", currentSoundsTask)
// Bundle JavaScript and React resources.
// (adapted from react-native/react.gradle)
//

View File

@ -43,10 +43,10 @@ PODS:
- React/Core
- React/fishhook
- React/RCTBlob
- RNSound (0.10.4):
- RNSound (0.10.9):
- React/Core
- RNSound/Core (= 0.10.4)
- RNSound/Core (0.10.4):
- RNSound/Core (= 0.10.9)
- RNSound/Core (0.10.9):
- React/Core
- RNVectorIcons (4.4.2):
- React
@ -103,7 +103,7 @@ SPEC CHECKSUMS:
react-native-keep-awake: 0de4bd66de0c23178107dce0c2fcc3354b2a8e94
react-native-locale-detector: d1b2c6fe5abb56e3a1efb6c2d6f308c05c4251f1
react-native-webrtc: bc044ca9530fc802e7533f247aa08fe1b6bf8dc5
RNSound: d0818fe2435254fe30540fae48a429c5ffb72e09
RNSound: b360b3862d3118ed1c74bb9825696b5957686ac4
RNVectorIcons: c0dbfbf6068fefa240c37b0f71bd03b45dddac44
yoga: 17521bbb0dd54a47c0b3ac43253e78cdac7488e0

View File

@ -27,6 +27,8 @@
0BCA496C1EC4BBF900B793EE /* jitsi.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0BCA496B1EC4BBF900B793EE /* jitsi.ttf */; };
0BD906EA1EC0C00300C8C18E /* JitsiMeet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BD906E81EC0C00300C8C18E /* JitsiMeet.h */; settings = {ATTRIBUTES = (Public, ); }; };
0F65EECE1D95DA94561BB47E /* libPods-JitsiMeet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 03F2ADC957FF109849B7FCA1 /* libPods-JitsiMeet.a */; };
75635B0A20751D6D00F29C9F /* joined.wav in Resources */ = {isa = PBXBuildFile; fileRef = 75635B0820751D6D00F29C9F /* joined.wav */; };
75635B0B20751D6D00F29C9F /* left.wav in Resources */ = {isa = PBXBuildFile; fileRef = 75635B0920751D6D00F29C9F /* left.wav */; };
C6245F5D2053091D0040BE68 /* image-resize@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = C6245F5B2053091D0040BE68 /* image-resize@2x.png */; };
C6245F5E2053091D0040BE68 /* image-resize@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = C6245F5C2053091D0040BE68 /* image-resize@3x.png */; };
C6A3425F204EF76800E062DD /* PiPWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6A3425C204EF76800E062DD /* PiPWindow.swift */; };
@ -60,6 +62,8 @@
0BD906E51EC0C00300C8C18E /* JitsiMeet.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = JitsiMeet.framework; sourceTree = BUILT_PRODUCTS_DIR; };
0BD906E81EC0C00300C8C18E /* JitsiMeet.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JitsiMeet.h; sourceTree = "<group>"; };
0BD906E91EC0C00300C8C18E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
75635B0820751D6D00F29C9F /* joined.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = joined.wav; path = ../../sounds/joined.wav; sourceTree = "<group>"; };
75635B0920751D6D00F29C9F /* left.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = left.wav; path = ../../sounds/left.wav; sourceTree = "<group>"; };
98E09B5C73D9036B4ED252FC /* Pods-JitsiMeet.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JitsiMeet.debug.xcconfig"; path = "../Pods/Target Support Files/Pods-JitsiMeet/Pods-JitsiMeet.debug.xcconfig"; sourceTree = "<group>"; };
9C77CA3CC919B081F1A52982 /* Pods-JitsiMeet.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JitsiMeet.release.xcconfig"; path = "../Pods/Target Support Files/Pods-JitsiMeet/Pods-JitsiMeet.release.xcconfig"; sourceTree = "<group>"; };
C6245F5B2053091D0040BE68 /* image-resize@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "image-resize@2x.png"; path = "src/picture-in-picture/image-resize@2x.png"; sourceTree = "<group>"; };
@ -89,6 +93,8 @@
0BCA49681EC4BBE500B793EE /* Resources */ = {
isa = PBXGroup;
children = (
75635B0820751D6D00F29C9F /* joined.wav */,
75635B0920751D6D00F29C9F /* left.wav */,
0BC4B8681F8C01E100CE8B21 /* CallKitIcon.png */,
C6245F5B2053091D0040BE68 /* image-resize@2x.png */,
C6245F5C2053091D0040BE68 /* image-resize@3x.png */,
@ -252,6 +258,8 @@
0BCA496C1EC4BBF900B793EE /* jitsi.ttf in Resources */,
C6245F5D2053091D0040BE68 /* image-resize@2x.png in Resources */,
0BC4B8691F8C03A700CE8B21 /* CallKitIcon.png in Resources */,
75635B0B20751D6D00F29C9F /* left.wav in Resources */,
75635B0A20751D6D00F29C9F /* joined.wav in Resources */,
C6245F5E2053091D0040BE68 /* image-resize@3x.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;

View File

@ -45,8 +45,11 @@ RCT_EXPORT_MODULE();
}
}
NSString *sdkBundlePath = [[NSBundle bundleForClass:self.class] bundlePath];
return @{
@"name": name,
@"sdkBundlePath": sdkBundlePath,
@"version": version
};
};

6
package-lock.json generated
View File

@ -10405,9 +10405,9 @@
"integrity": "sha1-QeDsKqfdjxLzo+6Dr51jxLZw+KE="
},
"react-native-sound": {
"version": "0.10.4",
"resolved": "https://registry.npmjs.org/react-native-sound/-/react-native-sound-0.10.4.tgz",
"integrity": "sha512-V9v4CjKgv8ekQRLOJSoKA7pxJ03F4Ih3T/RfMIlMWLktz7v/O4sdJPjRBLOzZRqAnr9FWTLbSk1ZCjioXh3mjQ=="
"version": "0.10.9",
"resolved": "https://registry.npmjs.org/react-native-sound/-/react-native-sound-0.10.9.tgz",
"integrity": "sha1-awCw9K/QF83gn7udFx3xtdW4Uag="
},
"react-native-vector-icons": {
"version": "4.4.2",

View File

@ -64,7 +64,7 @@
"react-native-keep-awake": "2.0.6",
"react-native-locale-detector": "github:jitsi/react-native-locale-detector#cc76092fc4335488a28a9529c8b50afae2c3ecdc",
"react-native-prompt": "1.0.0",
"react-native-sound": "0.10.4",
"react-native-sound": "0.10.9",
"react-native-vector-icons": "4.4.2",
"react-native-webrtc": "github:jitsi/react-native-webrtc#84aee6693195c5be6b6f5f794a1e52dc7913fb3b",
"react-redux": "5.0.6",

View File

@ -11,3 +11,13 @@ export * from './getRouteToRender';
export function getName() {
return NativeModules.AppInfo.name;
}
/**
* Returns the path to the Jitsi Meet SDK bundle on iOS. On Android it will be
* undefined.
*
* @returns {string|undefined}
*/
export function getSdkBundlePath() {
return NativeModules.AppInfo.sdkBundlePath;
}

View File

@ -44,7 +44,7 @@ export default class Audio extends AbstractAudio {
this._sound
= this.props.src
? new Sound(
this.props.src,
this.props.src, null,
this._soundLoadedCallback.bind(this))
: null;
}

View File

@ -34,10 +34,7 @@ import {
getParticipantById,
getParticipantCount
} from './functions';
import {
PARTICIPANT_JOINED_SRC,
PARTICIPANT_LEFT_SRC
} from './sounds';
import { PARTICIPANT_JOINED_FILE, PARTICIPANT_LEFT_FILE } from './sounds';
declare var APP: Object;
@ -214,9 +211,9 @@ function _maybePlaySounds({ getState, dispatch }, action) {
*/
function _registerSounds({ dispatch }) {
dispatch(
registerSound(PARTICIPANT_JOINED_SOUND_ID, PARTICIPANT_JOINED_SRC));
registerSound(PARTICIPANT_JOINED_SOUND_ID, PARTICIPANT_JOINED_FILE));
dispatch(
registerSound(PARTICIPANT_LEFT_SOUND_ID, PARTICIPANT_LEFT_SRC));
registerSound(PARTICIPANT_LEFT_SOUND_ID, PARTICIPANT_LEFT_FILE));
}
/**
@ -228,7 +225,7 @@ function _registerSounds({ dispatch }) {
*/
function _unregisterSounds({ dispatch }) {
dispatch(
unregisterSound(PARTICIPANT_JOINED_SOUND_ID, PARTICIPANT_JOINED_SRC));
unregisterSound(PARTICIPANT_JOINED_SOUND_ID));
dispatch(
unregisterSound(PARTICIPANT_LEFT_SOUND_ID, PARTICIPANT_LEFT_SRC));
unregisterSound(PARTICIPANT_LEFT_SOUND_ID));
}

View File

@ -0,0 +1,11 @@
/**
* The name of the bundled sound file which will be played when new participant
* joins the conference.
*/
export const PARTICIPANT_JOINED_FILE = 'joined.wav';
/**
* The name of the bundled sound file which will be played when any participant
* leaves the conference.
*/
export const PARTICIPANT_LEFT_FILE = 'left.wav';

View File

@ -1,13 +0,0 @@
/**
* Points to the sound file which will be played when new participant joins
* the conference.
*/
export const PARTICIPANT_JOINED_SRC
= require('../../../../sounds/joined.wav');
/**
* Points to the sound file which will be played when any participant leaves
* the conference.
*/
export const PARTICIPANT_LEFT_SRC
= require('../../../../sounds/left.wav');

View File

@ -1,11 +0,0 @@
/**
* Points to the sound file which will be played when new participant joins
* the conference.
*/
export const PARTICIPANT_JOINED_SRC = 'sounds/joined.wav';
/**
* Points to the sound file which will be played when any participant leaves
* the conference.
*/
export const PARTICIPANT_LEFT_SRC = 'sounds/left.wav';

View File

@ -9,6 +9,7 @@ import {
REGISTER_SOUND,
UNREGISTER_SOUND
} from './actionTypes';
import { getSoundsPath } from './functions';
/**
* Adds {@link AudioElement} instance to the base/sounds feature state for the
@ -81,20 +82,19 @@ export function playSound(soundId: string): Object {
*
* @param {string} soundId - The global identifier which identify the sound
* created for given source object.
* @param {Object|string} src - Either path to an audio file or a raw object
* which specifies the audio resource that will be associated with the given
* {@code soundId}.
* @param {string} soundName - The name of bundled audio file that will be
* associated with the given {@code soundId}.
* @returns {{
* type: REGISTER_SOUND,
* soundId: string,
* src: (Object | string)
* src: string
* }}
*/
export function registerSound(soundId: string, src: Object | string): Object {
export function registerSound(soundId: string, soundName: string): Object {
return {
type: REGISTER_SOUND,
soundId,
src
src: `${getSoundsPath()}/${soundName}`
};
}

View File

@ -0,0 +1,9 @@
/**
* Returns the location of the sounds. On Android sounds files are copied to
* the 'assets/sounds/' folder of the SDK bundle on build time.
*
* @returns {string}
*/
export function getSoundsPath() {
return 'asset:/sounds';
}

View File

@ -0,0 +1,12 @@
import { getSdkBundlePath } from '../../app';
/**
* Returns the location of the sounds. On iOS it's the location of the SDK
* bundle on the phone. Each sound file must be added to the SDK's XCode project
* in order to be bundled correctly.
*
* @returns {string}
*/
export function getSoundsPath() {
return getSdkBundlePath();
}

View File

@ -0,0 +1,9 @@
/**
* Returns the location of the sounds. On Web it's the relative path to
* the sounds folder placed in the source root.
*
* @returns {string}
*/
export function getSoundsPath() {
return 'sounds';
}

View File

@ -7,7 +7,7 @@ import { MiddlewareRegistry } from '../base/redux';
import { playSound, registerSound, unregisterSound } from '../base/sounds';
import { INCOMING_MSG_SOUND_ID } from './constants';
import { INCOMING_MSG_SOUND_SRC } from './sounds';
import { INCOMING_MSG_SOUND_FILE } from './sounds';
declare var APP: Object;
@ -24,7 +24,7 @@ MiddlewareRegistry.register(store => next => action => {
// on mobile.
typeof APP === 'undefined'
|| store.dispatch(
registerSound(INCOMING_MSG_SOUND_ID, INCOMING_MSG_SOUND_SRC));
registerSound(INCOMING_MSG_SOUND_ID, INCOMING_MSG_SOUND_FILE));
break;
case APP_WILL_UNMOUNT:

View File

@ -1,6 +1,7 @@
/**
* The audio source for the incoming chat message sound.
* The name of the bundled audio file which will be played for the incoming chat
* message sound.
*
* @type {string}
*/
export const INCOMING_MSG_SOUND_SRC = 'sounds/incomingMessage.wav';
export const INCOMING_MSG_SOUND_FILE = 'incomingMessage.wav';