feat: local volume

This commit is contained in:
TrueZhuanjia
2025-09-23 23:51:21 +08:00
parent 431b32b680
commit e5669e2a30
16 changed files with 162 additions and 13 deletions
+26 -4
View File
@@ -1135,6 +1135,26 @@
<constraint firstAttribute="height" constant="31" id="Gs7-g5-VMU"/>
</constraints>
</stackView>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="a8q-4l-07i" userLabel="localVolumeStack">
<rect key="frame" x="440" y="2507" width="380" height="55.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Local Volume" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="AeU-kl-XFa" userLabel="uiLabel">
<rect key="frame" x="0.0" y="0.0" width="380" height="20.5"/>
<color key="tintColor" red="0.81533776120000001" green="0.85979419950000002" blue="0.91372549020000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<slider verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="100" minValue="0.0" maxValue="100" translatesAutoresizingMaskIntoConstraints="NO" id="aDm-fu-eWR">
<rect key="frame" x="-2" y="25.5" width="384" height="31"/>
<color key="tintColor" systemColor="linkColor"/>
</slider>
</subviews>
<constraints>
<constraint firstAttribute="height" constant="55.5" id="Kaw-h7-D2V"/>
<constraint firstAttribute="width" constant="380" id="Oij-e2-w81"/>
</constraints>
</stackView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
@@ -1182,6 +1202,8 @@
<outlet property="liftStreamViewForKeyboardStack" destination="mes-so-dfK" id="nXR-Ot-Ydf"/>
<outlet property="localMousePointerModeSelector" destination="4FU-iP-c6T" id="4Gz-ao-xH2"/>
<outlet property="localMousePointerModeStack" destination="nE1-Al-qRc" id="2hC-Xi-icX"/>
<outlet property="localVolumeSlider" destination="aDm-fu-eWR" id="hR5-TW-rBf"/>
<outlet property="localVolumeStack" destination="a8q-4l-07i" id="cvW-nq-R7I"/>
<outlet property="mousePointerVelocityFactorSlider" destination="Ei2-FJ-9oC" id="1T3-QA-Jua"/>
<outlet property="mousePointerVelocityFactorUILabel" destination="oPM-G6-u5O" id="Eco-5u-PRR"/>
<outlet property="mousePointerVelocityStack" destination="aQ8-4e-CQB" id="CW3-el-Yc3"/>
@@ -1958,7 +1980,7 @@
<image name="tray.full.fill" catalog="system" width="128" height="88"/>
<image name="video.and.waveform" catalog="system" width="128" height="94"/>
<systemColor name="linkColor">
<color red="0.0" green="0.47843137254901963" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="secondarySystemGroupedBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
@@ -1967,13 +1989,13 @@
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
<systemColor name="systemBrownColor">
<color red="0.63529411764705879" green="0.51764705882352946" blue="0.36862745098039218" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color red="0.63529411759999999" green="0.51764705879999995" blue="0.36862745099999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemGray3Color">
<color red="0.7803921568627451" green="0.7803921568627451" blue="0.80000000000000004" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color red="0.78039215689999997" green="0.78039215689999997" blue="0.80000000000000004" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemTealColor">
<color red="0.18823529411764706" green="0.69019607843137254" blue="0.7803921568627451" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color red="0.18823529410000001" green="0.69019607839999997" blue="0.78039215689999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
</resources>
</document>
+26 -4
View File
@@ -1868,6 +1868,26 @@
<constraint firstAttribute="height" constant="31" id="Dxt-TV-Fs3"/>
</constraints>
</stackView>
<stackView verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="zmq-ah-Vfh" userLabel="localVolumeStack">
<rect key="frame" x="437" y="1235" width="380" height="55.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Local Volume" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="GbY-52-itv" userLabel="uiLabel">
<rect key="frame" x="0.0" y="0.0" width="380" height="20.5"/>
<color key="tintColor" red="0.81533776120000001" green="0.85979419950000002" blue="0.91372549020000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<slider verifyAmbiguity="off" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="100" minValue="0.0" maxValue="100" translatesAutoresizingMaskIntoConstraints="NO" id="7xn-es-SaH">
<rect key="frame" x="-2" y="25.5" width="384" height="31"/>
<color key="tintColor" systemColor="linkColor"/>
</slider>
</subviews>
<constraints>
<constraint firstAttribute="height" constant="55.5" id="Y3K-cU-wGj"/>
<constraint firstAttribute="width" constant="380" id="wiK-dT-C4c"/>
</constraints>
</stackView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
@@ -1915,6 +1935,8 @@
<outlet property="liftStreamViewForKeyboardStack" destination="mgf-RQ-AVP" id="xH0-F0-dth"/>
<outlet property="localMousePointerModeSelector" destination="zLl-8w-K8J" id="jsc-Tp-zwe"/>
<outlet property="localMousePointerModeStack" destination="IKt-3O-raJ" id="vkn-5N-4Jl"/>
<outlet property="localVolumeSlider" destination="7xn-es-SaH" id="au4-HZ-ff6"/>
<outlet property="localVolumeStack" destination="zmq-ah-Vfh" id="88M-AX-mh6"/>
<outlet property="mousePointerVelocityFactorSlider" destination="bXi-Xx-6MW" id="fEw-YV-154"/>
<outlet property="mousePointerVelocityFactorUILabel" destination="hn6-X9-TaI" id="wfS-k3-5B0"/>
<outlet property="mousePointerVelocityStack" destination="VfU-iM-hP1" id="bgC-E9-tsz"/>
@@ -1989,19 +2011,19 @@
<image name="trash.fill" catalog="system" width="117" height="128"/>
<image name="tray.full.fill" catalog="system" width="128" height="88"/>
<systemColor name="linkColor">
<color red="0.0" green="0.47843137254901963" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="secondarySystemGroupedBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
<systemColor name="systemBrownColor">
<color red="0.63529411764705879" green="0.51764705882352946" blue="0.36862745098039218" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color red="0.63529411759999999" green="0.51764705879999995" blue="0.36862745099999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemGray2Color">
<color red="0.68235294117647061" green="0.68235294117647061" blue="0.69803921568627447" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color red="0.68235294120000001" green="0.68235294120000001" blue="0.69803921570000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemTealColor">
<color red="0.18823529411764706" green="0.69019607843137254" blue="0.7803921568627451" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color red="0.18823529410000001" green="0.69019607839999997" blue="0.78039215689999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
</resources>
</document>
+1
View File
@@ -76,6 +76,7 @@ typedef NS_ENUM(NSInteger, WidgetSizeTransition) {
touchPointerVelocityFactor:(CGFloat)touchPointerVelocityFactor
mousePointerVelocityFactor:(CGFloat)mousePointerVelocityFactor
gyroSensitivity:(CGFloat)gyroSensitivity
localVolume:(CGFloat)localVolume
touchMoveEventInterval:(NSInteger)touchMoveEventInterval
reverseMouseWheelDirection:(BOOL)reverseMouseWheelDirection
asyncNativeTouchPriority:(NSInteger)asyncNativeTouchPriority
+2
View File
@@ -71,6 +71,7 @@
touchPointerVelocityFactor:(CGFloat)touchPointerVelocityFactor
mousePointerVelocityFactor:(CGFloat)mousePointerVelocityFactor
gyroSensitivity:(CGFloat)gyroSensitivity
localVolume:(CGFloat)localVolume
touchMoveEventInterval:(NSInteger)touchMoveEventInterval
reverseMouseWheelDirection:(BOOL)reverseMouseWheelDirection
asyncNativeTouchPriority:(NSInteger)asyncNativeTouchPriority
@@ -121,6 +122,7 @@
settingsToSave.touchPointerVelocityFactor = [NSNumber numberWithFloat:touchPointerVelocityFactor];
settingsToSave.mousePointerVelocityFactor = [NSNumber numberWithFloat:mousePointerVelocityFactor];
settingsToSave.gyroSensitivity = [NSNumber numberWithFloat:gyroSensitivity];
settingsToSave.localVolume = [NSNumber numberWithFloat:localVolume];
settingsToSave.touchMoveEventInterval = [NSNumber numberWithInteger:touchMoveEventInterval];
settingsToSave.reverseMouseWheelDirection = reverseMouseWheelDirection;
settingsToSave.asyncNativeTouchPriority = [NSNumber numberWithInteger:asyncNativeTouchPriority];
+1
View File
@@ -33,6 +33,7 @@
@property (nonatomic, retain) NSNumber * touchMoveEventInterval;
@property (nonatomic, retain) NSNumber * touchPointerVelocityFactor;
@property (nonatomic, retain) NSNumber * gyroSensitivity;
@property (nonatomic, retain) NSNumber * localVolume;
@property (nonatomic, retain) NSNumber * emulatedControllerType;
@property (nonatomic, retain) NSNumber * mousePointerVelocityFactor;
@property (nonatomic, retain) NSNumber * pointerVelocityModeDivider;
+1
View File
@@ -116,6 +116,7 @@
self.touchPointerVelocityFactor = settings.touchPointerVelocityFactor;
self.mousePointerVelocityFactor = settings.mousePointerVelocityFactor;
self.gyroSensitivity = settings.gyroSensitivity;
self.localVolume = settings.localVolume;
self.pointerVelocityModeDivider = settings.pointerVelocityModeDivider;
self.unlockDisplayOrientation = settings.unlockDisplayOrientation;
self.resolutionSelected = settings.resolutionSelected;
@@ -44,6 +44,7 @@
<attribute name="keyboardToggleFingers" optional="YES" attributeType="Integer 16" defaultValueString="3" usesScalarValueType="NO" syncable="YES"/>
<attribute name="liftStreamViewForKeyboard" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/>
<attribute name="localMousePointerMode" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/>
<attribute name="localVolume" optional="YES" attributeType="Float" defaultValueString="1" usesScalarValueType="NO" syncable="YES"/>
<attribute name="mousePointerVelocityFactor" optional="YES" attributeType="Float" defaultValueString="1" usesScalarValueType="NO" syncable="YES"/>
<attribute name="multiController" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/>
<attribute name="onscreenControls" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/>
+1
View File
@@ -22,5 +22,6 @@
-(BandwidthTracker *) getBwTracker;
-(BOOL) getVideoStats:(video_stats_t*)stats;
-(NSString*) getActiveCodecName;
+ (void)setVolume:(float)newVolume;
@end
+21
View File
@@ -44,6 +44,7 @@ static NSLock* videoStatsLock;
static SDL_AudioDeviceID audioDevice;
static OPUS_MULTISTREAM_CONFIGURATION audioConfig;
static void* audioBuffer;
static float volume = 1.0;
static int audioFrameSize;
static VideoDecoderRenderer* renderer;
@@ -302,6 +303,13 @@ void ArCleanup(void)
SDL_QuitSubSystem(SDL_INIT_AUDIO);
}
+ (void)setVolume:(float)linearVolume{
if (linearVolume <= 0.0f) linearVolume = 0.0f;
if (linearVolume >= 1.0f) linearVolume = 1.0f;
CGFloat exponent = 2.5;
volume = powf(linearVolume, exponent);
}
void ArDecodeAndPlaySample(char* sampleData, int sampleLength)
{
int decodeLen;
@@ -318,9 +326,20 @@ void ArDecodeAndPlaySample(char* sampleData, int sampleLength)
(float*)audioBuffer,
audioConfig.samplesPerFrame,
0);
if (decodeLen > 0) {
// Provide backpressure on the queue to ensure too many frames don't build up
// in SDL's audio queue.
float* fbuf = (float*)audioBuffer;
if(volume != 1.0){
int totalSamples = decodeLen * audioConfig.channelCount;
for (int i = 0; i < totalSamples; i++) {
fbuf[i] *= volume;
}
}
while (SDL_GetQueuedAudioSize(audioDevice) / audioFrameSize > 10) {
[NSThread sleepForTimeInterval:0.001f];
}
@@ -470,6 +489,8 @@ void ClSetControllerLED(uint16_t controllerNumber, uint8_t r, uint8_t g, uint8_t
_streamConfig.supportedVideoFormats = config.supportedVideoFormats;
_streamConfig.audioConfiguration = config.audioConfiguration;
_streamConfig.redirectMic = config.redirectMic && [MicHandler permissionGranted];
NSLog(@"config.localVolume %f", config.localVolume);
[Connection setVolume:config.localVolume];
// Since we require iOS 12 or above, we're guaranteed to be running
// on a 64-bit device with ARMv8 crypto instructions, so we don't
+1
View File
@@ -42,5 +42,6 @@
@property BOOL multiController;
@property NSData* serverCert;
@property int localMousePointerMode;
@property CGFloat localVolume;
@end
+1 -1
View File
@@ -9,5 +9,5 @@
#import "StreamConfiguration.h"
@implementation StreamConfiguration
@synthesize host, httpsPort, appID, width, height, frameRate, bitRate, riKeyId, riKey, gamepadMask, appName, optimizeGameSettings, playAudioOnPC, swapABXYButtons, buttonVisualFeedback, gyroMode, emulatedControllerType, audioConfiguration, supportedVideoFormats, multiController, serverCert, rtspSessionUrl, serverCodecModeSupport, enableYUV444, enablePIP;
@synthesize host, httpsPort, appID, width, height, frameRate, bitRate, riKeyId, riKey, gamepadMask, appName, optimizeGameSettings, playAudioOnPC, swapABXYButtons, buttonVisualFeedback, gyroMode, emulatedControllerType, audioConfiguration, supportedVideoFormats, multiController, serverCert, rtspSessionUrl, serverCodecModeSupport, enableYUV444, enablePIP, localVolume;
@end
@@ -821,6 +821,7 @@ static NSMutableSet* hostList;
_streamConfig.optimizeGameSettings = streamSettings.optimizeGames;
_streamConfig.playAudioOnPC = streamSettings.playAudioOnPC;
_streamConfig.redirectMic = streamSettings.redirectMic;
_streamConfig.localVolume = streamSettings.localVolume.floatValue;
_streamConfig.swapABXYButtons = streamSettings.swapABXYButtons;
_streamConfig.buttonVisualFeedback = streamSettings.buttonVisualFeedback;
_streamConfig.asyncNativeTouchPriority = streamSettings.asyncNativeTouchPriority; // new streamConfig segment
@@ -135,6 +135,9 @@
@property (strong, nonatomic) IBOutlet UIStackView *sendDummyEventStack;
@property (strong, nonatomic) IBOutlet UISwitch *sendDummyEventSwitch;
@property (strong, nonatomic) IBOutlet UIStackView *localVolumeStack;
@property (strong, nonatomic) IBOutlet UISlider *localVolumeSlider;
@property (nonatomic, strong) MicHandler *micHandler;
@@ -12,6 +12,7 @@
#import "TemporarySettings.h"
#import "DataManager.h"
#import "ThemeManager.h"
#import "Connection.h"
#import "Plot.h"
#import <UIKit/UIGestureRecognizerSubclass.h>
@@ -674,6 +675,7 @@ BOOL isCustomResolution(int resolutionSelected) {
}
[self addSetting:self.audioOnPcStack ofId:@"audioOnPcStack" withInfoTag:NO withDynamicLabel:NO to:audioSection];
[self addSetting:self.localVolumeStack ofId:@"localVolumeStack" withInfoTag:NO withDynamicLabel:YES to:audioSection];
[self addSetting:self.redirectMicStack ofId:@"redirectMicStack" withInfoTag:YES withDynamicLabel:NO to:audioSection];
[self addSetting:self.audioConfigStack ofId:@"audioConfigStack" withInfoTag:NO withDynamicLabel:NO to:audioSection];
[audioSection addToParentStack:_parentStack];
@@ -1549,10 +1551,13 @@ BOOL isCustomResolution(int resolutionSelected) {
[self.emulatedControllerTypeSelector setSelectedSegmentIndex:[self controllerTypeToSegmentIndex:tempSettings.emulatedControllerType.intValue]];
[self.emulatedControllerTypeSelector addTarget:self action:@selector(emulatedControllerTypeChanged:) forControlEvents:(UIControlEventValueChanged)]; // Update label display when slider is being moved.
[self emulatedControllerTypeChanged:self.emulatedControllerTypeSelector];
[self.audioOnPcSwitch setOn:tempSettings.playAudioOnPC];
[self.localVolumeSlider setValue:tempSettings.localVolume.floatValue*100];
[self.localVolumeSlider addTarget:self action:@selector(localVolumeSliderMoved:) forControlEvents:UIControlEventValueChanged];
[self localVolumeSliderMoved:self.localVolumeSlider];
[self.redirectMicSwitch setOn:tempSettings.redirectMic];
[self.redirectMicSwitch addTarget:self action:@selector(redirectMicSwitchFlipped:) forControlEvents:UIControlEventValueChanged];
[self redirectMicSwitchFlipped:self.redirectMicSwitch];
@@ -1903,7 +1908,6 @@ BOOL isCustomResolution(int resolutionSelected) {
[self presentViewController:self.layoutOnScreenControlsVC animated:YES completion:nil];
}
- (void) pointerVelocityModeDividerSliderMoved:(UISlider* )sender {
[self findDynamicLabelFromStack:self.pointerVelocityDividerStack].text = [NSString stringWithFormat:@" | %d%% | %d%% | ", (uint8_t)sender.value, 100-(uint8_t)sender.value];
}
@@ -1916,6 +1920,11 @@ BOOL isCustomResolution(int resolutionSelected) {
[self findDynamicLabelFromStack:self.gyroSensitivityStack].text = [NSString stringWithFormat:@" %d%% ", (uint16_t)sender.value]; // Update label display
}
- (void) localVolumeSliderMoved:(UISlider* )sender {
[self findDynamicLabelFromStack:self.localVolumeStack].text = [NSString stringWithFormat:@" %d%% ", (uint16_t)sender.value]; // Update label display
if(_mainFrameViewController.settingsExpandedInStreamView) [Connection setVolume:sender.value/100];
}
- (void) backgroundSessionTimerSliderMoved:(UISlider* )sender {
NSString* labelString;
labelString = [LocalizationHelper localizedStringForKey:@" keep %d min ", (uint16_t)sender.value];
@@ -2464,6 +2473,8 @@ BOOL isCustomResolution(int resolutionSelected) {
CGFloat touchPointerVelocityFactor = (CGFloat)(uint16_t)[self map_velocFactorDisplay_fromSliderValue:self.touchPointerVelocityFactorSlider.value]/100;
CGFloat mousePointerVelocityFactor = (CGFloat)(uint16_t)[self map_velocFactorDisplay_fromSliderValue:self.mousePointerVelocityFactorSlider.value]/100;
CGFloat gyroSensitivity = (CGFloat)(uint16_t)self.gyroSensitivitySlider.value/100;
CGFloat localVolume = self.localVolumeSlider.value/100;
uint16_t touchMoveEventInterval = (uint16_t)self.touchMoveEventIntervalSlider.value;
@@ -2517,6 +2528,7 @@ BOOL isCustomResolution(int resolutionSelected) {
touchPointerVelocityFactor:touchPointerVelocityFactor
mousePointerVelocityFactor:mousePointerVelocityFactor
gyroSensitivity:gyroSensitivity
localVolume:localVolume
touchMoveEventInterval:touchMoveEventInterval
reverseMouseWheelDirection:reverseMouseWheelDirection
asyncNativeTouchPriority:asyncNativeTouchPriority
+30
View File
@@ -679,6 +679,36 @@
}
}
},
"AeU-kl-XFa.text" : {
"comment" : "Class = \"UILabel\"; text = \"Local Volume\"; ObjectID = \"AeU-kl-XFa\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Local Volume"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "本地音量"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "本地音量"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "本地音量"
}
}
}
},
"aFy-0w-YPe.segmentTitles[0]" : {
"comment" : "Class = \"UISegmentedControl\"; aFy-0w-YPe.segmentTitles[0] = \"H.264\"; ObjectID = \"aFy-0w-YPe\";",
"extractionState" : "extracted_with_value",
+30
View File
@@ -1561,6 +1561,36 @@
}
}
},
"GbY-52-itv.text" : {
"comment" : "Class = \"UILabel\"; text = \"Local Volume\"; ObjectID = \"GbY-52-itv\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Local Volume"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "本地音量"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "本地音量"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "本地音量"
}
}
}
},
"ghM-zc-sr6.title" : {
"comment" : "Class = \"UIBarButtonItem\"; title = \"Delete\"; ObjectID = \"ghM-zc-sr6\";",
"extractionState" : "extracted_with_value",