Closed A-viral-dev closed 1 year ago
Yes, unfortunately it doesn't work on some vivo devices: https://github.com/Genymobile/scrcpy/pull/3757#issuecomment-1454326127 https://github.com/Genymobile/scrcpy/issues/3791#issuecomment-1465214771
Following the discussion from #3791 (because here is the right place for this issue).
I asked to pull the following .jar
:
adb pull /system/framework/framework.jar
adb pull /system/framework/vivo-framework.jar
adb pull /system/framework/vivo-media.jar
Here are the links you provided:
/system/framework/framework.jar
/system/framework/vivo-framework.jar
/system/framework/vivo-media.jar
And the list of available jarfiles in /system/framework
:
The class VivoAudioRecordImpl
is found in vivo-framework.jar
. Here are the relevant parts:
public class VivoAudioRecordImpl implements IVivoAudioRecord {
// …
private Context mContext;
// …
public VivoAudioRecordImpl() {
Application currentApplication = ActivityThread.currentApplication();
this.mContext = currentApplication;
if (currentApplication != null) {
this.mAudioFeatures = new AudioFeatures(this.mContext, (String) null, (Object) null);
} else {
this.mAudioFeatures = null;
}
}
// …
public String isSupportSubMixRecording() {
AudioFeatures.TagParameters tp = new AudioFeatures.TagParameters("vivo_remote_support");
String mPackageName = this.mContext.getOpPackageName();
String PackSha256 = getSignInfo(this.mContext, mPackageName, SHA256);
tp.put(VivoPermissionManager.ACTION_KEY_PACKAGE, mPackageName);
tp.put("component", PackSha256);
tp.put(Calendar.CalendarAlertsColumns.STATE, VRequest.COMMAND_QUERY);
String ret = new AudioFeatures.TagParameters(this.mAudioFeatures.getAudioFeature(tp.toString(), this)).get(Calendar.CalendarAlertsColumns.STATE);
VLog.w(TAG, "isSupportSubMixRecording:" + ret + " PackSha256:" + PackSha256);
return ret;
}
// …
}
However, I did not find from where it is called. According to your stacktrace, it's from android.media.AudioRecord
. This class is available in your framework.jar
, but does not call isSupportSubMixRecording()
.
In any case, the obvious first attempt is to make the context initialized. This is what I did here. However, it was not suffient. So I don't know what to do.
isSupportSubMixRecording
is being called from AudioRecord
's constructor,
try {
AudioAttributes attributes3 = attributes2;
try {
int initResult = native_setup(new WeakReference(this), this.mAudioAttributes, sampleRate, this.mChannelMask, this.mChannelIndexMask, this.mAudioFormat, this.mNativeBufferSizeInBytes, session, attributionSourceState.getParcel(), 0L, maxSharedAudioHistoryMs);
if (initResult != 0) {
loge("Error code " + initResult + " when initializing native AudioRecord object.");
if (attributionSourceState != null) {
attributionSourceState.close();
return;
}
return;
}
if (attributionSourceState != null) {
attributionSourceState.close();
}
this.mSampleRate = sampleRate[0];
this.mSessionId = session[0];
IVivoAudioRecord iVivoAudioRecord = this.mVivoAudioRecord;
if (iVivoAudioRecord == null) {
i = 1;
} else {
String result = iVivoAudioRecord.isSupportSubMixRecording(); // <--- here
if (!"true".equals(result) || attributes3.getCapturePreset() != 8) {
i = 1;
} else {
i = 1;
this.mIsLiveApp = true;
this.mVivoAudioRecord.notifyGamecube(1);
this.mVivoAudioRecord.showNotificationStatus(true);
Log.d(TAG, "notifyGamecube start by " + this);
}
}
this.mState = i;
} catch (Throwable th2) {
th = th2;
if (attributionSourceState != null) {
try {
attributionSourceState.close();
} catch (Throwable th3) {
th.addSuppressed(th3);
}
}
throw th;
}
} catch (Throwable th4) {
th = th4;
}
But looking at isSupportSubMixRecording
, maybe vivo only allows some apps to capture remote submix, Even if we have all methods on context, it might still not work.
The query request was sent to system_server, which should be in services.jar
or vivo-services.jar
isSupportSubMixRecording
is being called fromAudioRecord
's constructor,
I don't have this code in the AudioRecord.java
from framework.jar
. How did you decompile?
I'm using jadx https://github.com/skylot/jadx
Oh, I used jadx too, but an old version (v1.2.0). With the latest (v1.4.6), I get the same source as you :tada:
IVivoAudioRecord iVivoAudioRecord = this.mVivoAudioRecord;
if (iVivoAudioRecord == null) {
i = 1;
} else {
String result = iVivoAudioRecord.isSupportSubMixRecording();
Maybe we can force mVivoAudioRecord
to be null
:see_no_evil:
Let's try. @A-viral-dev please replace this binary in the v2.0 release, and run with scrcpy -Vdebug
:
scrcpy-server
SHA-256: 682d39c1cbe24ae1279378b1c13b4d28106407ae5fa26db72613fdfeaec7f5e8
`aviralshivpuri@penguin:~$ scrcpy -Vdebug
scrcpy 2.0 <https://github.com/Genymobile/scrcpy>
DEBUG: ADB device found:
DEBUG: --> (tcpip) 192.168.29.216:5555 device I2202
DEBUG: Device serial: 192.168.29.216:5555
DEBUG: Using server: /usr/local/share/scrcpy/scrcpy-server
/usr/local/share/scrcpy/scrcpy-server: 1 file pushed. 1.4 MB/s (129307 bytes in 0.086s)
[server] INFO: Device: vivo I2202 (Android 13)
DEBUG: Server connected
DEBUG: Starting controller thread
DEBUG: Starting receiver thread
INFO: Renderer: opengl
INFO: OpenGL version: 3.1 Mesa 21.2.6
INFO: Trilinear filtering enabled
DEBUG: Using icon: /usr/local/share/icons/hicolor/256x256/apps/scrcpy.png
DEBUG: Demuxer 'video': starting thread
DEBUG: Demuxer 'audio': starting thread
[server] DEBUG: Using encoder: 'OMX.qcom.video.encoder.avc'
INFO: Initial texture: 1080x2400
[server] DEBUG: Using audio encoder: 'c2.android.opus.encoder'
WARN: Demuxer 'audio': stream explicitly disabled by the device
[server] DEBUG: Audio encoder stopped
[server] ERROR: Exception on thread Thread[Thread-4,5,main]
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getOpPackageName()' on a null object reference
at android.media.VivoAudioRecordImpl.isSupportSubMixRecording(VivoAudioRecordImpl.java:133)
at android.media.AudioRecord.<init>(AudioRecord.java:493)
at android.media.AudioRecord.<init>(Unknown Source:0)
at android.media.AudioRecord$Builder.build(AudioRecord.java:999)
at com.genymobile.scrcpy.AudioCapture.createAudioRecord(AudioCapture.java:58)
at com.genymobile.scrcpy.AudioCapture.start(AudioCapture.java:92)
at com.genymobile.scrcpy.AudioEncoder.encode(AudioEncoder.java:183)
at com.genymobile.scrcpy.AudioEncoder.lambda$start$0$com-genymobile-scrcpy-AudioEncoder(AudioEncoder.java:120)
at com.genymobile.scrcpy.AudioEncoder$$ExternalSyntheticLambda0.run(Unknown Source:2)
at java.lang.Thread.run(Thread.java:1012)`
Still no audio
The call is in the constructor, must get the instance before the call, doesn't seem to be possible.
Full decompiled source: https://gist.github.com/yume-chan/0e061cc819865d78d717b226513c27e9
Maybe invoke the AudioRecord(long nativeRecordInJavaObj)
constructor by reflection (with 0
) and do all initialization (native_setup
) in Scrcpy?
The call is in the constructor
Oh, it was so far below that I thought it was in another method. :facepalm:
Please try this: scrcpy-server.zip
D:\Download\scrcpy-win64-v2.0>scrcpy.exe scrcpy 2.0 https://github.com/Genymobile/scrcpy D:\Download\scrcpy-win64-v2.0\scrcpy-server: 1 file pushed, 0 skipped. 68.7 MB/s (62140 bytes in 0.001s) [server] INFO: Device: vivo V2118A (Android 12) INFO: Renderer: direct3d INFO: Initial texture: 1080x2408 [server] ERROR: Audio capture error java.io.IOException: Could not read audio: 0 at com.genymobile.scrcpy.AudioEncoder.inputThread(AudioEncoder.java:96) at com.genymobile.scrcpy.AudioEncoder.lambda$encode$1$com-genymobile-scrcpy-AudioEncoder(AudioEncoder.java:189) at com.genymobile.scrcpy.AudioEncoder$$ExternalSyntheticLambda1.run(Unknown Source:6) at java.lang.Thread.run(Thread.java:922)
met other issue exception in my vivo phone
That's with a newer build from dev
branch. Ibdon't have any solution fornvivo phones.
great sound start to work
scrcpy 2.0 <https://github.com/Genymobile/scrcpy>
/usr/local/share/scrcpy/scrcpy-server: 1 file pushed, 0 skipped. 117.7 MB/s (62140 bytes in 0.001s)
[server] INFO: Device: vivo I2202 (Android 13)
INFO: Renderer: opengl
INFO: OpenGL version: 3.1 Mesa 21.2.6
INFO: Trilinear filtering enabled
INFO: Initial texture: 1080x2400
But
great sound start to work
Nice. Now let @rom1v decide whether to use this as a fallback path.
the sound from the device is only played on the computer and not on both devices.
Yes this is expected. Remote submix is like a sound output (like a earphone), so all audio outputs are redirected to it.
@yume-chan Great :+1:
However, I'm a bit worried that it is a very specific/fragile code in the long run. On Android 11 it fails (because missing AttributeSource, but that's probably easy to fix). On Android 13 (non-vivo), it currently works though.
I think it should be used as a fallback, if the normal path fails, try this one instead.
It works on vanilla Android 12/13, but if another vendor also added some code to the constructor (that works with Scrcpy now), then the code will break them instead.
So no need to support Android 11, unless another vivo user with Android 11 reported an issue. Also little effort is required to maintain it, if it stopped working, I don't care, we can always declare the device as can't be supported.
OK, maybe. The code could may be moved in a new method Workarounds.createAudioRecord()
, and with native reflection (not to add a joor
dependency). I think it may be adapted for Android 11 too (just removing the AttributeSource stuff).
Please tell me if you want to work on a proper PR to implement it. Otherwise, I could do it later.
I can create a PR this weekend.
Please try this (only for testing whether vivo has an allowlist for capturing remote submix): scrcpy-server.zip
diff
It worked for me
Please try this: scrcpy-server.zip
diff
@yume-chan
还是不行啊大佬
E:\touping\scrcpy-win64-v2.0\scrcpy-server: 1 file pushed, 0 skipped. 59.5 MB/s (62140 bytes in 0.001s) [server] INFO: Device: vivo V2055A (Android 11) [server] ERROR: createAudioRecord java.lang.NoClassDefFoundError: Failed resolution of: Landroid/content/AttributionSource$Builder; at com.genymobile.scrcpy.FakeContext.getAttributionSource(FakeContext.java:37) at com.genymobile.scrcpy.AudioCapture.createAudioRecord(AudioCapture.java:78) at com.genymobile.scrcpy.AudioCapture.start(AudioCapture.java:134) at com.genymobile.scrcpy.AudioEncoder.encode(AudioEncoder.java:183) at com.genymobile.scrcpy.AudioEncoder.lambda$start$0$com-genymobile-scrcpy-AudioEncoder(AudioEncoder.java:120) at com.genymobile.scrcpy.AudioEncoder$$ExternalSyntheticLambda0.run(Unknown Source:2) at java.lang.Thread.run(Thread.java:923) Caused by: java.lang.ClassNotFoundException: android.content.AttributionSource$Builder ... 7 more INFO: Renderer: direct3d INFO: Initial texture: 1080x2400 WARN: Demuxer 'audio': stream explicitly disabled by the device [server] ERROR: Exception on thread Thread[Thread-4,5,main] java.lang.NullPointerException: Attempt to invoke virtual method 'void android.media.AudioRecord.startRecording()' on a null object reference at com.genymobile.scrcpy.AudioCapture.start(AudioCapture.java:135) at com.genymobile.scrcpy.AudioEncoder.encode(AudioEncoder.java:183) at com.genymobile.scrcpy.AudioEncoder.lambda$start$0$com-genymobile-scrcpy-AudioEncoder(AudioEncoder.java:120) at com.genymobile.scrcpy.AudioEncoder$$ExternalSyntheticLambda0.run(Unknown Source:2) at java.lang.Thread.run(Thread.java:923)
有解决办法吗
@zwjgi #3862
@zwjgi #3862
Sorry I'm a beginner, can you tell me how to use it or just give me a scrcpy-server file
iqoo android 12 here, what is the solution for non coder ??
Please try this: scrcpy-server.zip
diff
it works for me (iqoo 9, android 13)
vivo x80 audio no work
@631jike Please test this version: https://github.com/Genymobile/scrcpy/pull/3862#issuecomment-1561871804
(To Vivo device users)
The Vivo issue with audio is fixed on dev
branch and it should work on the future scrcpy 2.1 release.
However, I'm afraid that a work-in-progress fix (#4015) for another device might break the fix for Vivo phones, so I need you to test the following version to make sure scrcpy 2.1 will still work on Vivo phones.
It basically contains the WIP fix branch and the following diff:
Here is a binary:
scrcpy-win64-issue3805.zip
SHA-256: 3bee1433d5d82b454dcf5a88213ca0b387ebfafc9e7b474ffc5aa3df713b18c8
Please run it with your Vivo phone and post the whole console output.
@rom1v
C:\Users\mr.song\Downloads\scrcpy-win64-issue3805\scrcpy-win64-v2.0-95-g9bff8ccad>scrcpy -Vdebug
scrcpy 2.0 <https://github.com/Genymobile/scrcpy>
DEBUG: ADB device found:
DEBUG: --> (usb) 3468348101003D0 device V2157A
DEBUG: Device serial: 3468348101003D0
DEBUG: Using server (portable): C:\Users\mr.song\Downloads\scrcpy-win64-issue3805\scrcpy-win64-v2.0-95-g9bff8ccad\scrcpy-server
C:\Users\mr.song\Downloads\scrcpy-win64-issue3805\scrcpy-w... file pushed, 0 skipped. 34.7 MB/s (57051 bytes in 0.002s)
[server] INFO: Device: [vivo] vivo V2157A (Android 13)
DEBUG: Server connected
DEBUG: Starting controller thread
DEBUG: Starting receiver thread
[server] DEBUG: Using video encoder: 'OMX.qcom.video.encoder.avc'
[server] DEBUG: Using audio encoder: 'c2.android.opus.encoder'
INFO: Renderer: direct3d
DEBUG: Trilinear filtering disable[server] DEBUG: Audio encoder stopped
d (not an OpenGL renderer
DEBUG: Using icon (portable): C:\Users\mr.song\Downloads\scrcpy-win64-issue3805\scrcpy-win64-v2.0-95-g9bff8ccad\icon.pngDEBUG: Demuxer 'video': starting thread
DEBUG: Demuxer 'audi[server] ERROR: Exception on thread Thread[audio-encoder,5,main]
o': starting thread
WARN: Demuxer 'java.lang.AssertionError: java.lang.reflect.InvocationTargetExceptiona
u at com.genymobile.scrcpy.wrappers.ActivityThread.<clinit>(ActivityThread.java:17)d
i at com.genymobile.scrcpy.wrappers.ActivityThread.getActivityThreadClass(ActivityThread.java:30)o
' at com.genymobile.scrcpy.FakeContext.retrieveSystemContext(FakeContext.java:23):
at com.genymobile.scrcpy.FakeContext.<init>(FakeContext.java:39)s
t at com.genymobile.scrcpy.FakeContext.<clinit>(FakeContext.java:19)r
e at com.genymobile.scrcpy.FakeContext.get(FakeContext.java:35)am exp
l at com.genymobile.scrcpy.AudioCapture.createAudioRecord(AudioCapture.java:57)i
c at com.genymobile.scrcpy.AudioCapture.startRecording(AudioCapture.java:107)i
t at com.genymobile.scrcpy.AudioCapture.start(AudioCapture.java:128)l
y at com.genymobile.scrcpy.AudioEncoder.encode(AudioEncoder.java:193)
d at com.genymobile.scrcpy.AudioEncoder.lambda$start$0$com-genymobile-scrcpy-AudioEncoder(AudioEncoder.java:124)i
s at com.genymobile.scrcpy.AudioEncoder$$ExternalSyntheticLambda0.run(Unknown Source:4)a
b at java.lang.Thread.run(Thread.java:1015)l
eCaused by: java.lang.reflect.InvocationTargetExceptiond
at java.lang.reflect.Constructor.newInstance0(Native Method)b
y at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
t at com.genymobile.scrcpy.wrappers.ActivityThread.<clinit>(ActivityThread.java:15)h
e ... 12 more
deCaused by: java.lang.RuntimeException: Can't create handler inside thread Thread[audio-encoder,5,main] that has not called Looper.prepare()v
i at android.os.Handler.<init>(Handler.java:227)c
e at android.os.Handler.<init>(Handler.java:129)
I at android.app.ActivityThread$H.<init>(ActivityThread.java:2262)N
F at android.app.ActivityThread.<init>(ActivityThread.java:420)O
: ... 15 more
Texture: 1080x2400
@Helaer Thank you very much, that helped a lot.
Could you please try this new version: https://github.com/Genymobile/scrcpy/issues/4015#issuecomment-1596192278 and confirm that audio still works on Vivo phones?
@Helaer Thank you very much, that helped a lot.
Could you please try this new version: #4015 (comment) and confirm that audio still works on Vivo phones?
@rom1v It works fine.
C:\Users\mr.song\Downloads\scrcpy-win64-issue4015\scrcpy-win64-v2.0-93-g86e5c90ed>scrcpy -Vdebug scrcpy 2.0 https://github.com/Genymobile/scrcpy DEBUG: ADB device found: DEBUG: --> (usb) 3468348101003D0 device V2157A DEBUG: Device serial: 3468348101003D0 DEBUG: Using server (portable): C:\Users\mr.song\Downloads\scrcpy-win64-issue4015\scrcpy-win64-v2.0-93-g86e5c90ed\scrcpy-server C:\Users\mr.song\Downloads\scrcpy-win64-issue4015\scrcpy-w... file pushed, 0 skipped. 37.2 MB/s (56923 bytes in 0.001s) [server] INFO: Device: [vivo] vivo V2157A (Android 13) [server] DEBUG: Using video encoder: 'OMX.qcom.video.encoder.avc' [server] DEBUG: Using audio encoder: 'c2.android.opus.encoder' DEBUG: Server connected DEBUG: Starting controller thread DEBUG: Starting receiver thread INFO: Renderer: direct3d DEBUG: Trilinear filtering disabled (not an OpenGL renderer DEBUG: Using icon (portable): C:\Users\mr.song\Downloads\scrcpy-win64-issue4015\scrcpy-win64-v2.0-93-g86e5c90ed\icon.png DEBUG: Demuxer 'video': starting thread DEBUG: Demuxer 'audio': starting thread INFO: Texture: 1080x2400 DEBUG: [Audio] Buffering threshold exceeded, skipping 240 samples DEBUG: [Audio] Buffering threshold exceeded, skipping 960 samples DEBUG: [Audio] Buffering threshold exceeded, skipping 480 samples DEBUG: [Audio] Buffering threshold exceeded, skipping 960 samples DEBUG: [Audio] Buffering threshold exceeded, skipping 960 samples DEBUG: [Audio] Buffering threshold exceeded, skipping 960 samples DEBUG: [Audio] Buffering threshold exceeded, skipping 480 samples
@Helaer Unfortunately, the version above did not work for Honor devices, so here is a new one which is confirmed to work on Honor devices: https://github.com/Genymobile/scrcpy/issues/4015#issuecomment-1597148925
Could you please confirm that it also works for Vivo devices?
不幸的是,上面的版本不适用于荣耀设备,所以这里有一个确认适用于荣耀设备的新版本:#4015(评论)
您能否确认它也适用于Vivo设备?
@rom1v It works fine.
C:\Users\mr.song\Downloads\scrcpy-win64-honor_6\scrcpy-win64-v2.0-94-g9f9b852ae>scrcpy -Vdebug scrcpy 2.0 https://github.com/Genymobile/scrcpy DEBUG: ADB device found: DEBUG: --> (usb) 3468348101003D0 device V2157A DEBUG: Device serial: 3468348101003D0 DEBUG: Using server (portable): C:\Users\mr.song\Downloads\scrcpy-win64-honor_6\scrcpy-win64-v2.0-94-g9f9b852ae\scrcpy-server C:\Users\mr.song\Downloads\scrcpy-win64-honor_6\scrcpy-win...file pushed, 0 skipped. 125.7 MB/s (56935 bytes in 0.000s) [server] INFO: Device: [vivo] vivo V2157A (Android 13) DEBUG: Server connected DEBUG: Starting controller thread DEBUG: Starting receiver thread [server] DEBUG: Using audio encoder: 'c2.android.opus.encoder' [server] DEBUG: Using video encoder: 'OMX.qcom.video.encoder.avc' INFO: Renderer: direct3d DEBUG: Trilinear filtering disabled (not an OpenGL renderer DEBUG: Using icon (portable): C:\Users\mr.song\Downloads\scrcpy-win64-honor_6\scrcpy-win64-v2.0-94-g9f9b852ae\icon.png DEBUG: Demuxer 'video': starting thread DEBUG: Demuxer 'audio': starting thread INFO: Texture: 1080x2400 DEBUG: [Audio] Buffering threshold exceeded, skipping 240 samples DEBUG: [Audio] Buffering threshold exceeded, skipping 480 samples DEBUG: [Audio] Buffer underflow, inserting silence: 87 samples DEBUG: [Audio] Buffer underflow, inserting silence: 240 samples DEBUG: [Audio] Buffer underflow, inserting silence: 240 samples
@Helaer In reference to https://github.com/Genymobile/scrcpy/issues/3805#issuecomment-1596148031, could you please test https://github.com/Genymobile/scrcpy/pull/5154?
@Helaer In reference to #3805 (comment), could you please test #5154?
@rom1v The audio works fine on my vivo device.
Oh, great 🎉 Thank you for the test :+1: