@capgo/capacitor-stream-call

中文文档
8.0.80发布于 2026/11/09MPL-2.0TypeScriptESM + CJS构建来源已验证近 30 天下载 6155

Uses the https://getstream.io/ SDK to implement calling in Capacitor

原始使用文档
文档目录40 节
  1. ➡️ Get started for free
  2. Key features
  3. Documentation
  4. Compatibility
  5. Installation
  6. Configuration
  7. iOS Setup
  8. Android Setup
  9. Displaying Caller Information
  10. Getting Caller Information
  11. Caller Information Structure
  12. Example Implementation
  13. API
  14. login(...)
  15. logout()
  16. call(...)
  17. endCall()
  18. joinCall(...)
  19. setMicrophoneEnabled(...)
  20. setCameraEnabled(...)
  21. addListener('callEvent', ...)
  22. addListener('incomingCall', ...)
  23. removeAllListeners()
  24. enableBluetooth()
  25. acceptCall()
  26. rejectCall()
  27. isCameraEnabled()
  28. getCallStatus()
  29. getRingingCall()
  30. toggleViews()
  31. setSpeaker(...)
  32. switchCamera(...)
  33. getCallInfo(...)
  34. setDynamicStreamVideoApikey(...)
  35. getDynamicStreamVideoApikey()
  36. getCurrentUser()
  37. getPluginVersion()
  38. Interfaces
  39. Type Aliases
  40. Enums

@capgo/capacitor-stream-call

Add video and audio calls to your Capacitor app with the Stream Video SDK, including incoming call handling and native call screens on iOS and Android.

Capgo - Build Capacitor apps with AI, ship updates instantly

Capgo: push fixes to your Capacitor users in minutes, build signed iOS and Android apps without a Mac, and roll back in one click.

➡️ Get started for free

14-day unlimited free trial. No credit card required

🤖 Building with an AI coding agent? Install Capgo skills so Claude Code, Codex, Cursor, Copilot, or Gemini CLI know how to install and use @capgo/capacitor-stream-call in your Capacitor app: npx skills add Cap-go/capgo-skills. Then ask your agent: "Add @capgo/capacitor-stream-call to my Capacitor app and wire it up." Agent setup guides · Hosted MCP

@capgo/capacitor-stream-call for Capacitor apps

Key features

  • Sessions: login() and logout() with a Stream user token.
  • Calls: call(), acceptCall(), rejectCall() and endCall(), with callEvent and incomingCall listeners.
  • Media controls: setMicrophoneEnabled(), setCameraEnabled(), switchCamera() and setSpeaker().
  • Call info: getCallStatus(), getCallInfo() and getCurrentUser().
  • Dynamic API key: setDynamicStreamVideoApikey() stores a Stream API key that native uses the next time it creates the client.
  • Platforms: iOS, Android and Web. Web uses the Stream video client.

Documentation

The most complete doc is available here: https://capgo.app/docs/plugins/streamcall/

Compatibility

Plugin versionCapacitor compatibilityMaintained
v8.*.*v8.*.*✅
v7.*.*v7.*.*On demand
v6.*.*v6.*.*❌
v5.*.*v5.*.*❌

Note: The major version of this plugin follows the major version of Capacitor. Use the version that matches your Capacitor installation (e.g., plugin v8 for Capacitor 8). Only the latest major version is actively maintained.

Installation

You can use our AI-Assisted Setup to install the plugin. Add the Capgo skills to your AI tool using the following command:

npx skills add https://github.com/cap-go/capacitor-skills --skill capacitor-plugins

Then use the following prompt:

Use the `capacitor-plugins` skill from `cap-go/capacitor-skills` to install the `@capgo/capacitor-stream-call` plugin in my project.

If you prefer Manual Setup, install the plugin by running the following commands and follow the platform-specific instructions below:

npm install @capgo/capacitor-stream-call
npx cap sync

Configuration

iOS Setup

1. API Key Configuration

Add your Stream Video API key to ios/App/App/Info.plist:

<dict>
  <key>CAPACITOR_STREAM_VIDEO_APIKEY</key>
  <string>your_api_key_here</string>
  <!-- other keys -->
</dict>

2. Localization (Optional)

To support multiple languages:

  1. Add localization files to your Xcode project:

    • /App/App/en.lproj/Localizable.strings
    • /App/App/en.lproj/Localizable.stringsdict
  2. Add translations in Localizable.strings:

"stream.video.call.incoming" = "Incoming call from %@";
"stream.video.call.accept" = "Accept";
"stream.video.call.reject" = "Reject";
"stream.video.call.hangup" = "Hang up";
"stream.video.call.joining" = "Joining...";
"stream.video.call.reconnecting" = "Reconnecting...";
  1. Configure localization in your AppDelegate.swift:
import StreamVideo

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        Appearance.localizationProvider = { key, table in
            Bundle.main.localizedString(forKey: key, value: nil, table: table)
        }
        return true
    }
}

Android Setup

1. API Key Configuration

Add your Stream Video API key to android/app/src/main/res/values/strings.xml:

<string name="CAPACITOR_STREAM_VIDEO_APIKEY">your_api_key_here</string>

2. MainActivity Configuration

Modify your MainActivity.java to handle incoming calls:

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  
  // Enable activity to show over lock screen
  if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O_MR1) {
    setShowWhenLocked(true);
    setTurnScreenOn(true);
  } else {
    getWindow().addFlags(android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | android.view.WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
  }
}

3. Application Class Configuration

Create or modify your Application class to initialize the plugin:

import ee.forgr.capacitor.streamcall.StreamCallPlugin;

@Override
public void onCreate() {
  super.onCreate();
  
  // Initialize Firebase
  com.google.firebase.FirebaseApp.initializeApp(this);
  
  // Pre-initialize StreamCall plugin
  try {
    StreamCallPlugin.preLoadInit(this, this);
  } catch (Exception e) {
    Log.e("App", "Failed to pre-initialize StreamVideo Plugin", e);
  }
}

Note: If you don't have an Application class, you need to create one and reference it in your AndroidManifest.xml with android:name=".YourApplicationClass".

4. Localization (Optional)

Add string resources for different languages:

Default (values/strings.xml):

<resources>
    <string name="stream_video_call_incoming">Incoming call from %1$s</string>
    <string name="stream_video_call_accept">Accept</string>
    <string name="stream_video_call_reject">Reject</string>
    <string name="stream_video_call_hangup">Hang up</string>
    <string name="stream_video_call_joining">Joining...</string>
    <string name="stream_video_call_reconnecting">Reconnecting...</string>
</resources>

French (values-fr/strings.xml):

<resources>
    <string name="stream_video_call_incoming">Appel entrant de %1$s</string>
    <string name="stream_video_call_accept">Accepter</string>
    <string name="stream_video_call_reject">Refuser</string>
    <string name="stream_video_call_hangup">Raccrocher</string>
    <string name="stream_video_call_joining">Connexion...</string>
    <string name="stream_video_call_reconnecting">Reconnexion...</string>
</resources>

Displaying Caller Information

When receiving incoming calls, you can access caller information including name, user ID, and profile image. This information is automatically extracted from the call data and passed through the event system.

Getting Caller Information

The caller information is available in two ways:

1. Through Call Events

The callEvent listener provides caller information for incoming calls:

StreamCall.addListener('callEvent', (event) => {
  if (event.state === 'ringing' && event.caller) {
    console.log('Incoming call from:', event.caller.name || event.caller.userId);
    console.log('Caller image:', event.caller.imageURL);
    // Update your UI to show caller information
    showIncomingCallUI(event.caller);
  }
});

2. Through Incoming Call Events (Android lock-screen)

The incomingCall listener also includes caller information:

StreamCall.addListener('incomingCall', (payload) => {
  if (payload.caller) {
    console.log('Lock-screen call from:', payload.caller.name || payload.caller.userId);
    // Update your lock-screen UI
    updateLockScreenUI(payload.caller);
  }
});

Caller Information Structure

interface CallMember {
  userId: string;      // User ID (always present)
  name?: string;       // Display name (optional)
  imageURL?: string;   // Profile image URL (optional)
  role?: string;       // User role (optional)
}

Example Implementation

Here's how to implement a proper incoming call screen with caller information:

export class CallService {
  private callerInfo: CallMember | null = null;

  constructor() {
    this.setupCallListeners();
  }

  private setupCallListeners() {
    StreamCall.addListener('callEvent', (event) => {
      if (event.state === 'ringing') {
        this.callerInfo = event.caller || null;
        this.showIncomingCallScreen();
      } else if (event.state === 'joined' || event.state === 'left') {
        this.callerInfo = null;
        this.hideIncomingCallScreen();
      }
    });

    // Android lock-screen support
    if (Capacitor.getPlatform() === 'android') {
      StreamCall.addListener('incomingCall', (payload) => {
        this.callerInfo = payload.caller || null;
        this.showLockScreenIncomingCall();
      });
    }
  }

  private showIncomingCallScreen() {
    const callerName = this.callerInfo?.name || 'Unknown Caller';
    const callerImage = this.callerInfo?.imageURL || 'default-avatar.png';
    
    // Update your UI components
    document.getElementById('caller-name').textContent = callerName;
    document.getElementById('caller-image').src = callerImage;
    document.getElementById('incoming-call-screen').style.display = 'block';
  }
}

API

login(...)

login(options: LoginOptions) => Promise<SuccessResponse>

Login to Stream Video service

ParamTypeDescription
optionsLoginOptions- Login configuration

Returns: Promise<SuccessResponse>


logout()

logout() => Promise<SuccessResponse>

Logout from Stream Video service

Returns: Promise<SuccessResponse>


call(...)

call(options: CallOptions) => Promise<SuccessResponse>

Initiate a call to another user

ParamTypeDescription
optionsCallOptions- Call configuration

Returns: Promise<SuccessResponse>


endCall()

endCall() => Promise<SuccessResponse>

End the current call

Returns: Promise<SuccessResponse>


joinCall(...)

joinCall(options: { callId: string; callType: string; }) => Promise<SuccessResponse>

Join an existing call

ParamTypeDescription
options{ callId: string; callType: string; }- Microphone state

Returns: Promise<SuccessResponse>


setMicrophoneEnabled(...)

setMicrophoneEnabled(options: { enabled: boolean; }) => Promise<SuccessResponse>

Enable or disable microphone

ParamTypeDescription
options{ enabled: boolean; }- Microphone state

Returns: Promise<SuccessResponse>


setCameraEnabled(...)

setCameraEnabled(options: { enabled: boolean; }) => Promise<SuccessResponse>

Enable or disable camera

ParamTypeDescription
options{ enabled: boolean; }- Camera state

Returns: Promise<SuccessResponse>


addListener('callEvent', ...)

addListener(eventName: 'callEvent', listenerFunc: (event: CallEvent) => void) => Promise<{ remove: () => Promise<void>; }>

Add listener for call events

ParamTypeDescription
eventName'callEvent'- Name of the event to listen for
listenerFunc(event: CallEvent) => void- Callback function

Returns: Promise<{ remove: () => Promise<void>; }>


addListener('incomingCall', ...)

addListener(eventName: 'incomingCall', listenerFunc: (event: IncomingCallPayload) => void) => Promise<{ remove: () => Promise<void>; }>

Listen for lock-screen incoming call (Android only). Fired when the app is shown by full-screen intent before user interaction.

ParamType
eventName'incomingCall'
listenerFunc(event: IncomingCallPayload) => void

Returns: Promise<{ remove: () => Promise<void>; }>


removeAllListeners()

removeAllListeners() => Promise<void>

Remove all event listeners


enableBluetooth()

enableBluetooth() => Promise<SuccessResponse>

Enable bluetooth audio

Returns: Promise<SuccessResponse>


acceptCall()

acceptCall() => Promise<SuccessResponse>

Accept an incoming call

Returns: Promise<SuccessResponse>


rejectCall()

rejectCall() => Promise<SuccessResponse>

Reject an incoming call

Returns: Promise<SuccessResponse>


isCameraEnabled()

isCameraEnabled() => Promise<CameraEnabledResponse>

Check if camera is enabled

Returns: Promise<CameraEnabledResponse>


getCallStatus()

getCallStatus() => Promise<CallEvent>

Get the current call status

Returns: Promise<CallEvent>


getRingingCall()

getRingingCall() => Promise<CallEvent>

Get the current ringing call

Returns: Promise<CallEvent>


toggleViews()

toggleViews() => Promise<{ newLayout: StreamCallLayout; }>

Cycle through the available video layouts

Returns: Promise<{ newLayout: StreamCallLayout; }>


setSpeaker(...)

setSpeaker(options: { name: string; }) => Promise<SuccessResponse>

Set speakerphone on

ParamTypeDescription
options{ name: string; }- Speakerphone name

Returns: Promise<SuccessResponse>


switchCamera(...)

switchCamera(options: { camera: 'front' | 'back'; }) => Promise<SuccessResponse>

Switch camera

ParamTypeDescription
options{ camera: 'front' | 'back'; }- Camera to switch to

Returns: Promise<SuccessResponse>


getCallInfo(...)

getCallInfo(options: { callId: string; }) => Promise<CallEvent>

Get detailed information about an active call including caller details

ParamTypeDescription
options{ callId: string; }- Options containing the call ID

Returns: Promise<CallEvent>


setDynamicStreamVideoApikey(...)

setDynamicStreamVideoApikey(options: { apiKey: string; }) => Promise<SuccessResponse>

Set a dynamic Stream Video API key that overrides the static one

ParamTypeDescription
options{ apiKey: string; }- The API key to set

Returns: Promise<SuccessResponse>


getDynamicStreamVideoApikey()

getDynamicStreamVideoApikey() => Promise<DynamicApiKeyResponse>

Get the currently set dynamic Stream Video API key

Returns: Promise<DynamicApiKeyResponse>


getCurrentUser()

getCurrentUser() => Promise<CurrentUserResponse>

Get the current user's information

Returns: Promise<CurrentUserResponse>


getPluginVersion()

getPluginVersion() => Promise<{ version: string; }>

Get the native Capacitor plugin version

Returns: Promise<{ version: string; }>


Interfaces

SuccessResponse

PropTypeDescription
successbooleanWhether the operation was successful
callIdstring

LoginOptions

PropTypeDescription
tokenstringStream Video API token
userIdstringUser ID for the current user
namestringDisplay name for the current user
imageURLstringOptional avatar URL for the current user
apiKeystringStream Video API key
magicDivIdstringID of the HTML element where the video will be rendered
pushNotificationsConfigPushNotificationsConfig

PushNotificationsConfig

PropType
pushProviderNamestring
voipProviderNamestring

CallOptions

PropTypeDescription
userIdsstring[]User ID of the person to call
typeCallTypeType of call, defaults to 'default'
ringbooleanWhether to ring the other user, defaults to true
teamstringTeam name to call
videobooleanWhether to start the call with video enabled, defaults to false
customRecord< string, | string | boolean | number | null | Record<string, string | boolean | number | null> | string[] | boolean[] | number[] >Custom data to be passed to the call

CallEvent

PropTypeDescription
callIdstringID of the call
stateCallStateCurrent state of the call
userIdstringUser ID of the participant in the call who triggered the event
reasonstringReason for the call state change, if applicable
callerCallMemberInformation about the caller (for incoming calls)
membersCallMember[]List of call members
customRecord< string, | string | boolean | number | null | Record<string, string | boolean | number | null> | string[] | boolean[] | number[] >
countnumber

CallState

CallState is the current state of the call as seen by an SFU.

PropTypeDescription
participantsParticipant[]participants is the list of participants in the call. In large calls, the list could be truncated in which case, the list of participants contains fewer participants than the counts returned in participant_count. Anonymous participants are NOT included in the list.
startedAtTimestampstarted_at is the time the call session actually started.
participantCountParticipantCountparticipant_count contains the summary of the counts.
pinsPin[]the list of pins in the call. Pins are ordered in descending order (most important first).

Participant

those who are online in the call

PropTypeDescription
userIdstring
sessionIdstring
publishedTracksTrackType[]map of track id to track type
joinedAtTimestamp
trackLookupPrefixstring
connectionQualityConnectionQuality
isSpeakingboolean
isDominantSpeakerboolean
audioLevelnumber
namestring
imagestring
customStruct
rolesstring[]

Timestamp

A Timestamp represents a point in time independent of any time zone or local calendar, encoded as a count of seconds and fractions of seconds at nanosecond resolution. The count is relative to an epoch at UTC midnight on January 1, 1970, in the proleptic Gregorian calendar which extends the Gregorian calendar backwards to year one.

All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap second table is needed for interpretation, using a 24-hour linear smear.

The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By restricting to that range, we ensure that we can convert to and from RFC 3339 date strings.

Examples

Example 1: Compute Timestamp from POSIX time().

<a href="#timestamp">Timestamp</a> timestamp;
timestamp.set_seconds(time(NULL));
timestamp.set_nanos(0);

Example 2: Compute Timestamp from POSIX gettimeofday().

struct timeval tv;
gettimeofday(&tv, NULL);

<a href="#timestamp">Timestamp</a> timestamp;
timestamp.set_seconds(tv.tv_sec);
timestamp.set_nanos(tv.tv_usec * 1000);

Example 3: Compute Timestamp from Win32 GetSystemTimeAsFileTime().

FILETIME ft;
GetSystemTimeAsFileTime(&ft);
UINT64 ticks = (((UINT64)ft.dwHighDateTime) &lt;&lt; 32) | ft.dwLowDateTime;

// A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
// is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
<a href="#timestamp">Timestamp</a> timestamp;
timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));

Example 4: Compute Timestamp from Java System.currentTimeMillis().

long millis = System.currentTimeMillis();

<a href="#timestamp">Timestamp</a> timestamp = <a href="#timestamp">Timestamp</a>.newBuilder().setSeconds(millis / 1000)
    .setNanos((int) ((millis % 1000) * 1000000)).build();

Example 5: Compute Timestamp from Java Instant.now().

Instant now = Instant.now();

<a href="#timestamp">Timestamp</a> timestamp =
    <a href="#timestamp">Timestamp</a>.newBuilder().setSeconds(now.getEpochSecond())
        .setNanos(now.getNano()).build();

Example 6: Compute Timestamp from current time in Python.

timestamp = <a href="#timestamp">Timestamp</a>()
timestamp.GetCurrentTime()

JSON Mapping

In JSON format, the Timestamp type is encoded as a string in the RFC 3339 format. That is, the format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z" where {year} is always expressed using four digits while {month}, {day}, {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution), are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone is required. A proto3 JSON serializer should always use UTC (as indicated by "Z") when printing the Timestamp type and a proto3 JSON parser should be able to accept both UTC and other timezones (as indicated by an offset).

For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past 01:30 UTC on January 15, 2017.

In JavaScript, one can convert a Date object to this format using the standard toISOString() method. In Python, a standard datetime.datetime object can be converted to this format using strftime with the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use the Joda Time's ISODateTimeFormat.dateTime() to obtain a formatter capable of generating timestamps in this format.

PropTypeDescription
secondsstringRepresents seconds of UTC time since Unix epoch 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z inclusive.
nanosnumberNon-negative fractions of a second at nanosecond resolution. Negative second values with fractions must still have non-negative nanos values that count forward in time. Must be from 0 to 999,999,999 inclusive.

Struct

Struct represents a structured data value, consisting of fields which map to dynamically typed values. In some languages, Struct might be supported by a native representation. For example, in scripting languages like JS a struct is represented as an object. The details of that representation are described together with the proto support for the language.

The JSON representation for Struct is JSON object.

PropTypeDescription
fields{ [key: string]: Value; }Unordered map of dynamically typed values.

Value

Value represents a dynamically typed value which can be either null, a number, a string, a boolean, a recursive struct value, or a list of values. A producer of value is expected to set one of these variants. Absence of any variant indicates an error.

The JSON representation for Value is JSON value.

PropType
kind{ oneofKind: 'nullValue'; nullValue: NullValue; } | { oneofKind: 'numberValue'; numberValue: number; } | { oneofKind: 'stringValue'; stringValue: string; } | { oneofKind: 'boolValue'; boolValue: boolean; } | { oneofKind: 'structValue'; structValue: Struct; } | { oneofKind: 'listValue'; listValue: ListValue; } | { oneofKind: undefined; }

ListValue

ListValue is a wrapper around a repeated field of values.

The JSON representation for ListValue is JSON array.

PropTypeDescription
valuesValue[]Repeated field of dynamically typed values.

ParticipantCount

PropTypeDescription
totalnumberTotal number of participants in the call including the anonymous participants.
anonymousnumberTotal number of anonymous participants in the call.

Pin

PropTypeDescription
userIdstringthe user to pin
sessionIdstringthe user sesion_id to pin, if not provided, applies to all sessions

CallMember

PropTypeDescription
userIdstringUser ID of the member
namestringDisplay name of the user
imageURLstringProfile image URL of the user
rolestringRole of the user in the call

IncomingCallPayload

PropTypeDescription
cidstringFull call CID (e.g. default:123)
type'incoming'Event type (currently always "incoming")
callerCallMemberInformation about the caller
customRecord< string, | string | boolean | number | null | Record<string, string | boolean | number | null> | string[] | boolean[] | number[] >Custom data to be passed to the call
MethodSignatureDescription
getPluginVersion() => Promise<{ version: string; }>Get the native Capacitor plugin version

CameraEnabledResponse

PropType
enabledboolean

DynamicApiKeyResponse

PropTypeDescription
apiKeystring | nullThe dynamic API key if set, null if not
hasDynamicKeybooleanWhether a dynamic key is currently set

CurrentUserResponse

PropTypeDescription
userIdstringUser ID of the current user
namestringDisplay name of the current user
imageURLstringAvatar URL of the current user
isLoggedInbooleanWhether the user is currently logged in

Type Aliases

CallType

'default' | 'audio' | 'audio_room' | 'livestream' | 'development'

Record

Construct a type with a set of properties K of type T

{ [P in K]: T; }

CallState

'idle' | 'ringing' | 'joining' | 'reconnecting' | 'joined' | 'leaving' | 'left' | 'created' | 'session_started' | 'rejected' | 'participant_counts' | 'missed' | 'accepted' | 'ended' | 'camera_enabled' | 'camera_disabled' | 'speaker_enabled' | 'speaker_disabled' | 'microphone_enabled' | 'microphone_disabled' | 'outgoing_call_ended' | 'unknown'

StreamCallLayout

'grid' | 'spotlight' | 'dynamic' | 'fullScreen' | 'fullscreen'

Enums

TrackType

MembersValue
UNSPECIFIED0
AUDIO1
VIDEO2
SCREEN_SHARE3
SCREEN_SHARE_AUDIO4

ConnectionQuality

MembersValue
UNSPECIFIED0
POOR1
GOOD2
EXCELLENT3

NullValue

MembersValueDescription
NULL_VALUE0Null value.

版本与发布记录

@capgo/capacitor-stream-call 共发布 193 个版本,首次发布于 2025/03/04;过去 12 个月发布了 92 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
8.0.80latest2026/11/09今天
8.0.792026/11/036 天前
8.0.782026/11/036 天前
8.0.772026/11/026 天前
8.0.762026/11/027 天前
8.0.752026/10/2614 天前

其他发布通道:next → 0.0.25-alpha.0。

关于 @capgo/capacitor-stream-call 的常见问题

@capgo/capacitor-stream-call 是什么?

Uses the https://getstream.io/ SDK to implement calling in Capacitor

如何安装 @capgo/capacitor-stream-call?

在项目目录运行 npm install @capgo/capacitor-stream-call,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:@capacitor/core(>=8.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@capgo/capacitor-stream-call 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@capgo/capacitor-stream-call 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@capgo/capacitor-stream-call 可以商用吗?

@capgo/capacitor-stream-call 使用 MPL-2.0 许可。弱 Copyleft:可以商用,也可以和闭源代码一起使用;但如果分发时修改了 MPL 授权的文件,这些文件的修改需以 MPL 开源。以上为概括,不构成法律意见,请以许可原文为准。

@capgo/capacitor-stream-call 的下载量有多少?

根据 npm 官方下载统计,@capgo/capacitor-stream-call 在 2026/10/09 – 2026/11/07 这 30 天内被下载 6,155 次,日均约 205 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@capgo/capacitor-stream-call 还在维护吗?

最新版本 8.0.80 发布于 2026/11/09(今天);至今共发布 193 个版本,其中过去 12 个月发布了 92 个;首次发布于 2025/03/04。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。