Browse Source

Merge commit 'cea5dab3daa396b03c24c4919b94a1f7247bedc5' into lxm

weicu
lxm 2 years ago
parent
commit
2b7de011c0
  1. 44
      ios/Podfile.lock
  2. 21
      ios/Runner.xcodeproj/project.pbxproj
  3. 123
      ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
  4. 123
      ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved
  5. 36
      ios/Runner/GoogleService-Info.plist
  6. 30
      ios/Runner/Info.plist
  7. 10
      ios/Runner/RunnerRelease.entitlements
  8. 8
      lib/data/services/asr_service.dart
  9. 17
      lib/data/services/deapsound_ai_service.dart
  10. 270
      lib/data/services/speech_impl/xunfei_asr_service.dart
  11. 88
      lib/modules/login/controllers/facebookLogin.dart
  12. 7
      lib/modules/login/controllers/googleLogin.dart
  13. 6
      lib/modules/meeting/controllers/meeting_edit_controller.dart
  14. 50
      lib/modules/meeting/controllers/meeting_record_controller.dart
  15. 4
      lib/modules/meeting/views/meeting_edit_view.dart
  16. 10
      lib/modules/settings/controllers/settings_controller.dart
  17. 9
      lib/modules/splash/controllers/splash_controller.dart

44
ios/Podfile.lock

@ -264,18 +264,18 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/sqflite_darwin/darwin"
SPEC CHECKSUMS:
app_settings: 58017cd26b604ae98c3e65acbdd8ba173703cc82
app_settings: 5127ae0678de1dcc19f2293271c51d37c89428b2
AppAuth: d4f13a8fe0baf391b2108511793e4b479691fb73
audio_session: 19e9480dbdd4e5f6c4543826b2e8b0e4ab6145fe
audio_waveforms: cd736909ebc6b6a164eb74701d8c705ce3241e1c
device_info_plus: 97af1d7e84681a90d0693e63169a5d50e0839a0d
audio_session: 9bb7f6c970f21241b19f5a3658097ae459681ba0
audio_waveforms: a6dde7fe7c0ea05f06ffbdb0f7c1b2b2ba6cedcf
device_info_plus: 71ffc6ab7634ade6267c7a93088ed7e4f74e5896
FBAEMKit: cb719c53575a3be86ea873279f30d6a2c4e15881
FBSDKCoreKit: ecdb980a24633ccb012700299ceb16d0235e14d2
FBSDKCoreKit_Basics: 045101c4a9ef10c845347424d73a29aae02c3e43
FBSDKLoginKit: 69eb59b2f839aba635616df6e422acd0ca88030a
Firebase: d80354ed7f6df5f9aca55e9eb47cc4b634735eaf
firebase_auth: 3d848b9b866b201e5c8e0c06d8b2cec272fd8825
firebase_core: ac395f994af4e28f6a38b59e05a88ca57abeb874
firebase_auth: 9ebbd83276bf977dea1c74dfc199acf9d2a2f42f
firebase_core: 8d552814f6c01ccde5d88939fced4ec26f2f5510
FirebaseAppCheckInterop: 9664c858489710f682766ef54e2b6741d3b62070
FirebaseAuth: ad59a1a7b161e75f74c39f70179d2482d40e2737
FirebaseAuthInterop: 01a804fb074424fd58b92dd50dd0272277199356
@ -283,32 +283,32 @@ SPEC CHECKSUMS:
FirebaseCoreExtension: 3d3f2017a00d06e09ab4ebe065391b0bb642565e
FirebaseCoreInternal: df24ce5af28864660ecbd13596fc8dd3a8c34629
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
flutter_blue_plus_darwin: 3ea4ec9133b377febcc8a70b28cd2d2dc9242bd9
flutter_facebook_auth: 48be46091bd1a5cc5a66055f1228a9d99a28bfaa
flutter_image_compress_common: ec1d45c362c9d30a3f6a0426c297f47c52007e3e
flutter_local_notifications: df98d66e515e1ca797af436137b4459b160ad8c9
flutter_secure_storage: d33dac7ae2ea08509be337e775f6b59f1ff45f12
flutter_tts: 0f492aab6accf87059b72354fcb4ba934304771d
fluwx: daa284756ce53442b3d0417ceeda66e981906811
google_sign_in_ios: 4111e87aa5e24a4404f00ea13479f35e571969cc
flutter_blue_plus_darwin: 09444a26fb6bdef523e55b68fc1c59af5a877ea6
flutter_facebook_auth: 8a9ad5fbfc25b77e7a53ea8986866950b27edcae
flutter_image_compress_common: 1697a328fd72bfb335507c6bca1a65fa5ad87df1
flutter_local_notifications: 395056b3175ba4f08480a7c5de30cd36d69827e4
flutter_secure_storage: 1ed9476fba7e7a782b22888f956cce43e2c62f13
flutter_tts: b88dbc8655d3dc961bc4a796e4e16a4cc1795833
fluwx: 6bf9c5a3a99ad31b0de137dd92370a0d10a60f4b
google_sign_in_ios: 19297361f2c51d7d8ac0201b866ef1fa5d1f94a8
GoogleSignIn: d4281ab6cf21542b1cfaff85c191f230b399d2db
GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d
GTMAppAuth: f69bd07d68cd3b766125f7e072c45d7340dea0de
GTMSessionFetcher: 5aea5ba6bd522a239e236100971f10cb71b96ab6
image_picker_ios: c560581cceedb403a6ff17f2f816d7fea1421fc1
just_audio: a42c63806f16995daf5b219ae1d679deb76e6a79
image_picker_ios: 7fe1ff8e34c1790d6fff70a32484959f563a928a
just_audio: 4e391f57b79cad2b0674030a00453ca5ce817eed
libwebp: 02b23773aedb6ff1fd38cec7a77b81414c6842a8
Mantle: c5aa8794a29a022dfbbfc9799af95f477a69b62d
MicrosoftCognitiveServicesSpeech-iOS: 723eccb3e459bbb530df3d9bfe84a291074b09eb
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d
RecaptchaInterop: 7d1a4a01a6b2cb1610a47ef3f85f0c411434cb21
record_darwin: 3b1a8e7d5c0cbf45ad6165b4d83a6ca643d929c3
record_darwin: fb1f375f1d9603714f55b8708a903bbb91ffdb0a
SDWebImage: f84b0feeb08d2d11e6a9b843cb06d75ebf5b8868
SDWebImageWebPCoder: e38c0a70396191361d60c092933e22c20d5b1380
share_plus: 8b6f8b3447e494cca5317c8c3073de39b3600d1f
speech_to_text: 627d3fd2194770b51abb324ba45c2d39398f24a8
sqflite_darwin: 5a7236e3b501866c1c9befc6771dfd73ffb8702d
share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a
speech_to_text: 9dc43a5df3cbc2813f8c7cc9bd0fbf94268ed7ac
sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0
Try: 5ef669ae832617b3cee58cb2c6f99fb767a4ff96
WechatOpenSDK-XCFramework: 36fb2bea0754266c17184adf4963d7e6ff98b69f

21
ios/Runner.xcodeproj/project.pbxproj

@ -20,6 +20,7 @@
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
3406320CAE3314A73EF78043 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BBE10AD7954527B6BB12CFB /* Pods_RunnerTests.framework */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
591293932D9524D1004A65BB /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 591293922D9524D1004A65BB /* GoogleService-Info.plist */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
@ -68,6 +69,8 @@
331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
4A9190D0838960F143BDC158 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
5912938C2D9520CE004A65BB /* RunnerRelease.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = RunnerRelease.entitlements; sourceTree = "<group>"; };
591293922D9524D1004A65BB /* GoogleService-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
5BBE10AD7954527B6BB12CFB /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
@ -161,6 +164,7 @@
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
5912938C2D9520CE004A65BB /* RunnerRelease.entitlements */,
0A7A32E22D8DBA6D0047F746 /* VoiceInteractionService.swift */,
0A7A32E32D8DBA6D0047F746 /* VolcanoAIService.swift */,
0ADE296F2D8C6C450032BFCB /* AudioSessionManager.swift */,
@ -171,6 +175,7 @@
0A5EDC032D8B544100215E26 /* BluetoothMediaButtonHelper.swift */,
0A5EDBFB2D89C4FD00215E26 /* ClassicBluetoothHelper.swift */,
97C146FA1CF9000F007C117D /* Main.storyboard */,
591293922D9524D1004A65BB /* GoogleService-Info.plist */,
97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
97C147021CF9000F007C117D /* Info.plist */,
@ -265,6 +270,9 @@
Base,
);
mainGroup = 97C146E51CF9000F007C117D;
packageReferences = (
5912938D2D95215F004A65BB /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */,
);
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
projectDirPath = "";
projectRoot = "";
@ -293,6 +301,7 @@
0ADE29692D8C25660032BFCB /* silence.mp3 in Resources */,
0ADE296A2D8C25660032BFCB /* sample.mp3 in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
591293932D9524D1004A65BB /* GoogleService-Info.plist in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -750,6 +759,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/RunnerRelease.entitlements;
CURRENT_PROJECT_VERSION = 23;
DEVELOPMENT_TEAM = 42C82SZUVX;
ENABLE_BITCODE = NO;
@ -802,6 +812,17 @@
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
/* Begin XCRemoteSwiftPackageReference section */
5912938D2D95215F004A65BB /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/firebase/firebase-ios-sdk";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 11.10.0;
};
};
/* End XCRemoteSwiftPackageReference section */
};
rootObject = 97C146E61CF9000F007C117D /* Project object */;
}

123
ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

@ -0,0 +1,123 @@
{
"originHash" : "c63c63846d9c539229e96de38d6af51417e28c0ee9a0bc48bd0f0f19d923c329",
"pins" : [
{
"identity" : "abseil-cpp-binary",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/abseil-cpp-binary.git",
"state" : {
"revision" : "bbe8b69694d7873315fd3a4ad41efe043e1c07c5",
"version" : "1.2024072200.0"
}
},
{
"identity" : "app-check",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/app-check.git",
"state" : {
"revision" : "61b85103a1aeed8218f17c794687781505fbbef5",
"version" : "11.2.0"
}
},
{
"identity" : "firebase-ios-sdk",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/firebase-ios-sdk",
"state" : {
"revision" : "2e4a4daac9da51f79c131e76cb47e785dd7708c4",
"version" : "11.10.0"
}
},
{
"identity" : "googleappmeasurement",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleAppMeasurement.git",
"state" : {
"revision" : "defe1970a9099d47765592ebd7ac5f5e9fdb57c6",
"version" : "11.10.0"
}
},
{
"identity" : "googledatatransport",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleDataTransport.git",
"state" : {
"revision" : "617af071af9aa1d6a091d59a202910ac482128f9",
"version" : "10.1.0"
}
},
{
"identity" : "googleutilities",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleUtilities.git",
"state" : {
"revision" : "53156c7ec267db846e6b64c9f4c4e31ba4cf75eb",
"version" : "8.0.2"
}
},
{
"identity" : "grpc-binary",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/grpc-binary.git",
"state" : {
"revision" : "cc0001a0cf963aa40501d9c2b181e7fc9fd8ec71",
"version" : "1.69.0"
}
},
{
"identity" : "gtm-session-fetcher",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/gtm-session-fetcher.git",
"state" : {
"revision" : "4d70340d55d7d07cc2fdf8e8125c4c126c1d5f35",
"version" : "4.4.0"
}
},
{
"identity" : "interop-ios-for-google-sdks",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/interop-ios-for-google-sdks.git",
"state" : {
"revision" : "040d087ac2267d2ddd4cca36c757d1c6a05fdbfe",
"version" : "101.0.0"
}
},
{
"identity" : "leveldb",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/leveldb.git",
"state" : {
"revision" : "a0bc79961d7be727d258d33d5a6b2f1023270ba1",
"version" : "1.22.5"
}
},
{
"identity" : "nanopb",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/nanopb.git",
"state" : {
"revision" : "b7e1104502eca3a213b46303391ca4d3bc8ddec1",
"version" : "2.30910.0"
}
},
{
"identity" : "promises",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/promises.git",
"state" : {
"revision" : "540318ecedd63d883069ae7f1ed811a2df00b6ac",
"version" : "2.4.0"
}
},
{
"identity" : "swift-protobuf",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-protobuf.git",
"state" : {
"revision" : "d72aed98f8253ec1aa9ea1141e28150f408cf17f",
"version" : "1.29.0"
}
}
],
"version" : 3
}

123
ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved

@ -0,0 +1,123 @@
{
"originHash" : "c63c63846d9c539229e96de38d6af51417e28c0ee9a0bc48bd0f0f19d923c329",
"pins" : [
{
"identity" : "abseil-cpp-binary",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/abseil-cpp-binary.git",
"state" : {
"revision" : "bbe8b69694d7873315fd3a4ad41efe043e1c07c5",
"version" : "1.2024072200.0"
}
},
{
"identity" : "app-check",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/app-check.git",
"state" : {
"revision" : "61b85103a1aeed8218f17c794687781505fbbef5",
"version" : "11.2.0"
}
},
{
"identity" : "firebase-ios-sdk",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/firebase-ios-sdk",
"state" : {
"revision" : "2e4a4daac9da51f79c131e76cb47e785dd7708c4",
"version" : "11.10.0"
}
},
{
"identity" : "googleappmeasurement",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleAppMeasurement.git",
"state" : {
"revision" : "defe1970a9099d47765592ebd7ac5f5e9fdb57c6",
"version" : "11.10.0"
}
},
{
"identity" : "googledatatransport",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleDataTransport.git",
"state" : {
"revision" : "617af071af9aa1d6a091d59a202910ac482128f9",
"version" : "10.1.0"
}
},
{
"identity" : "googleutilities",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleUtilities.git",
"state" : {
"revision" : "53156c7ec267db846e6b64c9f4c4e31ba4cf75eb",
"version" : "8.0.2"
}
},
{
"identity" : "grpc-binary",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/grpc-binary.git",
"state" : {
"revision" : "cc0001a0cf963aa40501d9c2b181e7fc9fd8ec71",
"version" : "1.69.0"
}
},
{
"identity" : "gtm-session-fetcher",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/gtm-session-fetcher.git",
"state" : {
"revision" : "4d70340d55d7d07cc2fdf8e8125c4c126c1d5f35",
"version" : "4.4.0"
}
},
{
"identity" : "interop-ios-for-google-sdks",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/interop-ios-for-google-sdks.git",
"state" : {
"revision" : "040d087ac2267d2ddd4cca36c757d1c6a05fdbfe",
"version" : "101.0.0"
}
},
{
"identity" : "leveldb",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/leveldb.git",
"state" : {
"revision" : "a0bc79961d7be727d258d33d5a6b2f1023270ba1",
"version" : "1.22.5"
}
},
{
"identity" : "nanopb",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/nanopb.git",
"state" : {
"revision" : "b7e1104502eca3a213b46303391ca4d3bc8ddec1",
"version" : "2.30910.0"
}
},
{
"identity" : "promises",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/promises.git",
"state" : {
"revision" : "540318ecedd63d883069ae7f1ed811a2df00b6ac",
"version" : "2.4.0"
}
},
{
"identity" : "swift-protobuf",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-protobuf.git",
"state" : {
"revision" : "d72aed98f8253ec1aa9ea1141e28150f408cf17f",
"version" : "1.29.0"
}
}
],
"version" : 3
}

36
ios/Runner/GoogleService-Info.plist

@ -0,0 +1,36 @@
<?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>CLIENT_ID</key>
<string>907754492821-oc9e77svgmmlgouo0op7vv00e1hb8278.apps.googleusercontent.com</string>
<key>REVERSED_CLIENT_ID</key>
<string>com.googleusercontent.apps.907754492821-oc9e77svgmmlgouo0op7vv00e1hb8278</string>
<key>ANDROID_CLIENT_ID</key>
<string>907754492821-9jakqvathu61e6b8g95i41ssi7o4dnka.apps.googleusercontent.com</string>
<key>API_KEY</key>
<string>AIzaSyAvyBQcOXuO_q851vevqZIufsPRTMCe808</string>
<key>GCM_SENDER_ID</key>
<string>907754492821</string>
<key>PLIST_VERSION</key>
<string>1</string>
<key>BUNDLE_ID</key>
<string>com.yunqiinnovation.deepsound</string>
<key>PROJECT_ID</key>
<string>deepsound-e0e3d</string>
<key>STORAGE_BUCKET</key>
<string>deepsound-e0e3d.firebasestorage.app</string>
<key>IS_ADS_ENABLED</key>
<false></false>
<key>IS_ANALYTICS_ENABLED</key>
<false></false>
<key>IS_APPINVITE_ENABLED</key>
<true></true>
<key>IS_GCM_ENABLED</key>
<true></true>
<key>IS_SIGNIN_ENABLED</key>
<true></true>
<key>GOOGLE_APP_ID</key>
<string>1:907754492821:ios:246794fc44b23174145c9c</string>
</dict>
</plist>

30
ios/Runner/Info.plist

@ -2,6 +2,34 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>com.yunqiinnovation.deepsound</string>
<key>CFBundleURLSchemes</key>
<array>
<string>fb3829022037361855</string>
<string>com.googleusercontent.apps.907754492821-oc9e77svgmmlgouo0op7vv00e1hb8278</string>
</array>
</dict>
</array>
<key>FacebookAppID</key>
<string>3829022037361855</string>
<key>FacebookClientToken</key>
<string>193d0a2b1757c41cfa557ea8e8f21c33</string>
<key>FacebookDisplayName</key>
<string>Deepsound</string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>fbapi</string>
<string>fb-messenger-api</string>
<string>fbauth2</string>
<string>fbshareextension</string>
<string>googlechrome</string>
<string>googlechromes</string>
</array>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
@ -12,6 +40,8 @@
<string>DeepSound</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>NSUserTrackingUsageDescription</key>
<string>This application needs to access your tracking data in order to offer better personalized services and advertisements</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>

10
ios/Runner/RunnerRelease.entitlements

@ -0,0 +1,10 @@
<?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>keychain-access-groups</key>
<array>
<string>$(AppIdentifierPrefix)com.yunqiinnovation.deepsound</string>
</array>
</dict>
</plist>

8
lib/data/services/asr_service.dart

@ -62,6 +62,9 @@ class RecognitionEvent {
/// 检测到的语言
final String detectedLanguage;
/// 角色
final String role;
/// 错误信息(仅在 error 和 canceled 类型中有效)
final String error;
@ -69,6 +72,7 @@ class RecognitionEvent {
required this.type,
this.text = '',
this.detectedLanguage = '',
this.role = '',
this.error = '',
});
@ -96,7 +100,9 @@ class RecognitionEvent {
bool get isFinalResult => type == RecognitionEventType.finalResult;
/// 检查是否为错误
bool get isError => type == RecognitionEventType.error || type == RecognitionEventType.canceled;
bool get isError =>
type == RecognitionEventType.error ||
type == RecognitionEventType.canceled;
@override
String toString() {

17
lib/data/services/deapsound_ai_service.dart

@ -22,14 +22,25 @@ class DeapsoundAIService implements AiService {
final client = http.Client();
final url = Uri.parse('https://www.deapsound.com/ai/funcchat');
List contextsList = [];
String msg = '';
for (var i = 0; i < messages.length; i++) {
Map item = messages[i];
if (i < messages.length - 1) {
if (item['role'] == 'user') {
contextsList.add(item['content']);
}
} else {
msg = item['content'];
}
}
final headers = {
'Content-Type': 'application/json',
'Authorization': apiKey,
};
final requestBody = {
"msg": messages.last['content'],
};
final requestBody = {"contexts": contextsList, "msg": msg};
try {
final request = http.Request('POST', url)

270
lib/data/services/speech_impl/xunfei_asr_service.dart

@ -0,0 +1,270 @@
import 'dart:async';
import 'dart:convert';
import 'dart:typed_data';
import 'package:crypto/crypto.dart';
import 'package:record/record.dart';
import 'package:web_socket_channel/web_socket_channel.dart';
import '../../../core/utils/logger.dart';
import 'package:get/get.dart';
import '../asr_service.dart';
/// 讯飞 语音识别服务
///
class XunfeiAsrService extends GetxService implements AsrService {
final String baseUrl = 'wss://rtasr.xfyun.cn/v1/ws';
final int _chunkSize = 1280; // 每次发送的数据大小
final String appId = '43d87d22';
final String apiKey = '83f063755e8d342670002f50a4471d42';
AudioRecorder? recorder;
Timer? _timer;
WebSocketChannel? _channel;
bool isConnected = false; //是否链接
bool _isInitialized = false;
final List<String> _defaultSupportedLanguages = ['zh-CN'];
String _languageStr = 'cn';
// 连续识别相关
bool _isContinuousRecognitionActive = false;
StreamController<RecognitionEvent>? _eventStreamController;
@override
List<String> get supportedLanguages => _defaultSupportedLanguages;
Uint8List _buff = Uint8List(0); //音频缓存区
BytesBuilder _originaBytes = BytesBuilder(); //原始音频
bool isRecording = false;
@override
Future<bool> initialize({
List<String>? supportedLanguages,
}) async {
try {
final List<String> languages =
supportedLanguages ?? _defaultSupportedLanguages;
String languagetoStr = languages.first.split('-')[1].toLowerCase();
_languageStr = languagetoStr;
_isInitialized = true;
Logger.info('Azure 语音识别服务初始化成功');
return true;
} catch (e) {
Logger.error('Azure 语音识别服务初始化失败: $e');
_isInitialized = false;
rethrow;
}
}
@override
Future<RecognitionEvent> recognizeOnce() async {
if (!_isInitialized) {
await initialize();
}
try {
throw Exception('无效的识别结果格式');
} catch (e) {
Logger.error('语音识别失败: $e');
return RecognitionEvent.error(e.toString());
}
}
@override
Future<Stream<RecognitionEvent>> startContinuousRecognition() async {
if (!_isInitialized) {
await initialize();
}
try {
_eventStreamController = StreamController<RecognitionEvent>.broadcast();
await recorder?.dispose();
recorder = AudioRecorder();
Stream<Uint8List>? stream = await recorder?.startStream(
const RecordConfig(
sampleRate: 16000,
encoder: AudioEncoder.pcm16bits,
numChannels: 1,
),
);
isRecording = true;
stream?.listen((data) {
if (isRecording) {
_buff = _appendToBuffer(data);
_originaBytes.add(data);
}
});
await _tryConnecting();
_timer = Timer.periodic(const Duration(milliseconds: 40), (timer) async {
//每40毫秒读取一次数据
var frame = _getAudioData();
if (frame.isNotEmpty) {
_channel?.sink.add(frame);
}
});
_isContinuousRecognitionActive = true;
return _eventStreamController!.stream;
} catch (e) {
Logger.error('开始连续语音识别失败: $e');
rethrow;
}
}
//写入音频数据到缓存区中
Uint8List _appendToBuffer(Uint8List newData) {
var newBuffer = Uint8List(_buff.length + newData.length);
newBuffer.setAll(0, _buff);
newBuffer.setAll(_buff.length, newData);
return newBuffer;
}
//读取缓存区中一帧数据
Uint8List _getAudioData() {
if (_buff.length >= _chunkSize) {
// 从缓冲区中读取1280字节的数据
var data = _buff.sublist(0, _chunkSize);
// 移除已读取的数据
_buff = _buff.sublist(_chunkSize);
return data;
} else {
return _buff;
}
}
//尝试连接
Future<void> _tryConnecting() async {
try {
final url = _geturl();
_channel = WebSocketChannel.connect(Uri.parse(url));
_channel?.stream.timeout(const Duration(seconds: 10)); //设置超时时间
await _channel?.ready;
isConnected = true;
_channel?.stream.listen(
(message) {
_handle(message);
},
onError: (error) {
isConnected = false;
Logger.error('连接失败: $error');
},
onDone: () {
isConnected = false;
Logger.error('WebSocket 连接已关闭!');
},
cancelOnError: true,
);
} catch (e) {
Logger.error("初始化异常----------------$e");
}
}
//处理数据
void _handle(data) {
try {
final result = jsonDecode(data);
if (result['code'] == "0" && result['data'] != "") {
final data = jsonDecode(result['data']);
String msg = "";
String role = '';
List rtList = data['cn']['st']['rt'];
for (var rt in rtList) {
for (var ws in rt['ws']) {
for (var ws in ws['cw']) {
msg += ws['w'];
if (ws['rl'] != "0") {
role = ws['rl'];
}
}
}
}
Logger.info(
"识别到的内容 type:${data['cn']['st']['type']} msg:$msg rl:$role");
if (msg.isNotEmpty) {
if (data['cn']['st']['type'] == "0") {
_eventStreamController?.add(RecognitionEvent(
type: RecognitionEventType.finalResult,
text: msg,
role: role,
));
} else {
_eventStreamController?.add(RecognitionEvent(
type: RecognitionEventType.intermediateResult,
text: msg,
role: role,
));
}
}
}
} catch (e) {
Logger.error("接受消息异常 $e");
}
}
///获取链接地址
String _geturl() {
// 生成时间戳
String ts = (DateTime.now().millisecondsSinceEpoch ~/ 1000).toString();
// 计算 baseString
String baseString = md5.convert(utf8.encode(appId + ts)).toString();
// 计算 signa
var hmacSha1 = Hmac(sha1, utf8.encode(apiKey));
var signa = hmacSha1.convert(utf8.encode(baseString));
String signaBase64 = base64Encode(signa.bytes);
String url = "";
// 构建 WebSocket URL
url =
'$baseUrl?appid=$appId&ts=$ts&lang=$_languageStr&roleType=2&signa=${Uri.encodeComponent(signaBase64)}';
return url;
}
@override
Future<bool> stopContinuousRecognition() async {
try {
await recorder?.stop();
isRecording = false;
_timer?.cancel();
_buff = Uint8List(0);
_originaBytes = BytesBuilder();
if (isConnected) {
_channel?.sink.add(utf8.encode('{"end": true}')); //结束
}
_isContinuousRecognitionActive = false;
return true;
} catch (e) {
Logger.error('停止连续语音识别失败: $e');
rethrow;
}
}
@override
bool isContinuousRecognitionActive() {
return _isContinuousRecognitionActive;
}
@override
Future<void> dispose() async {
try {
await stopContinuousRecognition();
recorder?.dispose();
_channel?.sink.close();
_eventStreamController?.close();
_eventStreamController = null;
_isInitialized = false;
Logger.info('Azure 语音识别资源已释放');
} catch (e) {
Logger.error('释放语音识别资源失败: $e');
_isInitialized = false;
}
}
}

88
lib/modules/login/controllers/facebookLogin.dart

@ -1,6 +1,13 @@
import 'dart:convert';
import 'dart:io';
import 'dart:math';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_facebook_auth/flutter_facebook_auth.dart';
import 'package:get/get.dart';
import 'package:crypto/crypto.dart';
class Facebook {
String token = '';
@ -9,35 +16,90 @@ class Facebook {
String email = '';
String pictureurl = '';
String id = '';
String generateNonce([int length = 32]) {
const charset =
'0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._';
final random = Random.secure();
return List.generate(length, (_) => charset[random.nextInt(charset.length)])
.join();
}
/// Returns the sha256 hash of [input] in hex notation.
String sha256ofString(String input) {
final bytes = utf8.encode(input);
final digest = sha256.convert(bytes);
return digest.toString();
}
// FaceBook登录
// 修改后的 signInWithFacebook
Future<bool> signInWithFacebook() async {
try {
print("开始 Facebook 登录");
final LoginResult result = await FacebookAuth.instance.login();
print("Facebook 登录结果:$result");
final rawNonce = generateNonce();
final nonce = sha256ofString(rawNonce);
final LoginResult loginResult = await FacebookAuth.instance
.login(
loginTracking: LoginTracking.enabled,
nonce: nonce,
)
.catchError((onError) {
if (kDebugMode) {
//print(onError);
}
throw Exception(onError.message);
});
if (loginResult.accessToken == null) {
throw Exception(loginResult.message);
}
// Create a credential from the access token
OAuthCredential facebookAuthCredential;
if (result.status == LoginStatus.success) {
token = result.accessToken!.tokenString;
print("Facebook Token: $token");
print("tokenType${loginResult.accessToken!.type}");
final credential = FacebookAuthProvider.credential(token);
print("Facebook Token: $credential");
if (Platform.isIOS) {
// Create a credential from the access token
switch (loginResult.accessToken!.type) {
case AccessTokenType.classic:
final classicToken = loginResult.accessToken as ClassicToken;
token = classicToken.tokenString;
print('Token 字符串: ${classicToken.tokenString}');
print('classicToken值: ${classicToken}');
facebookAuthCredential = FacebookAuthProvider.credential(
classicToken.authenticationToken!,
);
break;
case AccessTokenType.limited:
final limitedToken = loginResult.accessToken as LimitedToken;
token = limitedToken.tokenString;
print('Token 字符串: ${limitedToken.tokenString}');
print('LimitedToken值: ${limitedToken}');
facebookAuthCredential = OAuthCredential(
providerId: 'facebook.com',
signInMethod: 'oauth',
idToken: limitedToken.tokenString,
rawNonce: rawNonce,
);
break;
}
} else {
facebookAuthCredential = FacebookAuthProvider.credential(
loginResult.accessToken!.tokenString,
);
token = loginResult.accessToken!.tokenString;
}
print('facebookAuthCredential值: ${facebookAuthCredential}');
if (facebookAuthCredential == null) {
throw Exception("Facebook Login Fail.");
}
final userData = await FacebookAuth.instance.getUserData();
name = userData["name"].toString();
email = userData["email"].toString();
pictureurl = userData["picture"]["data"]["url"].toString();
id = userData["id"].toString();
print("user login facebook ${userData..values}");
print("user login facebook ${email}${pictureurl}${name}${id}");
return true;
} else {
print("登录失败,状态:${result.status},消息:${result.message}");
return false;
}
} catch (e) {
print("Facebook 登录异常:$e");
return false;

7
lib/modules/login/controllers/googleLogin.dart

@ -33,6 +33,8 @@ class Google {
return true;
} else {
UserCredential userCredential = await loginGoogle();
token = await userCredential.user?.getIdToken();
print('Future响应数据tokenResult: $token');
if (token != "") {
return true;
} else {
@ -61,10 +63,7 @@ class Google {
// Obtain the auth details from the request
final GoogleSignInAuthentication? googleAuth =
await googleUser?.authentication;
accessToken = googleAuth?.accessToken;
token = googleAuth?.idToken;
print('loginGoogle:googleAuth?.idToken= ${token}');
print('loginGoogle:googleAuth?.accessToken= ${accessToken}');
// Create a new credential,
final credential = GoogleAuthProvider.credential(
accessToken: googleAuth?.accessToken,

6
lib/modules/meeting/controllers/meeting_edit_controller.dart

@ -62,13 +62,13 @@ class MeetingEditController extends GetxController
void confirm() async {
String content = contentController.text;
String firstContent =
content.length >= 20 ? content.substring(0, 20) : content;
content.length >= 30 ? content.substring(0, 30) : content;
String title = titleController.text.isNotEmpty
? titleController.text
: meetingDetailsController.meetingData.value.title;
Map<String, Object?> data = {
'title': title,
'firstContent': firstContent,
'firstContent': firstContent.replaceAll("\n", ""),
'seconds': meetingDetailsController.seconds,
'content': contentController.text,
};
@ -81,7 +81,7 @@ class MeetingEditController extends GetxController
final dataMap =
Map<String, dynamic>.from(meetingController.dataList[index]);
dataMap['title'] = title;
dataMap['content'] = firstContent;
dataMap['content'] = firstContent.replaceAll("\n", "");
dataMap['seconds'] = meetingDetailsController.seconds;
meetingController.dataList[index] = dataMap;
}

50
lib/modules/meeting/controllers/meeting_record_controller.dart

@ -5,6 +5,7 @@ import 'package:get/get.dart';
import '../../../data/services/asr_service.dart';
import '../../../data/services/db/sqflite_api.dart';
import '../../../data/services/speech_impl/xunfei_asr_service.dart';
import 'meeting_controller.dart';
class MeetingRecordController extends GetxController
@ -31,7 +32,8 @@ class MeetingRecordController extends GetxController
void onInit() {
super.onInit();
lottieController = AnimationController(vsync: this);
_asrService = Get.find<AsrService>();
Get.put(XunfeiAsrService());
_asrService = Get.find<XunfeiAsrService>();
final Map<String, dynamic> args = Get.arguments ?? {};
title = args['title'];
creationTime = DateTime.now().millisecondsSinceEpoch;
@ -41,7 +43,7 @@ class MeetingRecordController extends GetxController
void onClose() {
lottieController.dispose();
timer?.cancel();
_asrService.stopContinuousRecognition();
_asrService.dispose();
_recognitionSubscription?.cancel();
super.onClose();
}
@ -82,7 +84,6 @@ class MeetingRecordController extends GetxController
//结束录音
Future<void> _stopRecorder() async {
await _asrService.stopContinuousRecognition();
_recognitionSubscription?.cancel();
}
// 处理语音识别事件
@ -92,7 +93,7 @@ class MeetingRecordController extends GetxController
intermediateContent.value = event.text;
break;
case RecognitionEventType.finalResult:
finalContent.value += event.text;
finalContent.value += _spliceText(event);
intermediateContent.value = '';
break;
default:
@ -101,14 +102,49 @@ class MeetingRecordController extends GetxController
}
}
String _spliceText(RecognitionEvent event) {
String eventText = event.text;
String text = '';
if (finalContent.value.isNotEmpty) {
if (event.role != '') {
final punctuations = {
',',
'。',
'!',
'?',
';',
':',
',',
'.',
':',
';',
'!',
'?'
};
final firstChar = eventText[0];
if (punctuations.contains(firstChar)) {
text += '$firstChar\n';
eventText = eventText.substring(1);
} else {
text += '\n';
}
text += '说话人${event.role}:';
}
} else {
text += '说话人${event.role}:';
}
text += eventText;
return text;
}
// 完成
void complete() async {
String firstContent = finalContent.value.length >= 20
? finalContent.value.substring(0, 20)
String firstContent = finalContent.value.length >= 30
? finalContent.value.substring(0, 30)
: finalContent.value;
Map<String, Object?> data = {
'title': title,
'firstContent': firstContent,
'firstContent': firstContent.replaceAll("\n", ""),
'seconds': seconds.value,
'creationTime': creationTime,
'audio': [],

4
lib/modules/meeting/views/meeting_edit_view.dart

@ -237,14 +237,14 @@ class MeetingEditView extends GetView<MeetingEditController> {
controller: controller.contentController,
style: TextStyle(
color: isDarkMode ? Colors.white : Colors.black87,
fontSize: 16.sp,
fontSize: 14.sp,
),
maxLines: 50,
decoration: InputDecoration(
hintText: '编辑记录内容',
hintStyle: TextStyle(
color: isDarkMode ? Colors.white70 : Colors.black54,
fontSize: 16.sp,
fontSize: 14.sp,
),
fillColor: Colors.transparent,
border: InputBorder.none,

10
lib/modules/settings/controllers/settings_controller.dart

@ -8,6 +8,8 @@ import '../../../data/services/speech_factory.dart';
import '../models/language_model.dart';
//import '../../../data/models/user_model.dart';
import '../../../data/models/user_Info.dart';
import '../../../modules/login/controllers/googleLogin.dart';
import '../../../modules/login/controllers/facebookLogin.dart';
class SettingsController extends GetxController {
// 语言设置
@ -222,9 +224,15 @@ class SettingsController extends GetxController {
targetLanguage.value = temp;
}
void signOut() {
Future<void> signOut() async {
// 在此实现退出登录逻辑
_storage.write("logintoken", "");
_storage.write("user_info", "");
final google = Google();
final facebook = Facebook();
await google.signOutGoogle();
await facebook.signOutFacebook();
Get.offAllNamed('/login');
}
}

9
lib/modules/splash/controllers/splash_controller.dart

@ -76,10 +76,13 @@ class SplashController extends GetxController {
// 获取登录Token并跳转
Future<void> _navigateToLogin() async {
final isLoggedIn = await getLoginToken();
bool isLoggedIn = false;
final token = _storage.read('logintoken');
print('getLoginToken:进来了${token}');
if (token != null && token.isNotEmpty) {
isLoggedIn = await getLoginToken();
}
if (isLoggedIn) {
// Get.offAllNamed(Routes.login); // 跳转到登录页
// Get.offAllNamed(Routes.home); // 跳转到主页
Get.offAllNamed(Routes.pairing);
} else {
Get.offAllNamed(Routes.login); // 跳转到登录页

Loading…
Cancel
Save