├── Program.cs ├── README.md ├── Sra6.java ├── clientformyserver.cs └── scrcpy-server /Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | using System.Net.Sockets; 4 | using System.Diagnostics; 5 | using System.Threading; 6 | using System.IO; 7 | using OpenCvSharp; 8 | 9 | class Program 10 | { 11 | 12 | 13 | public static void Main() 14 | { 15 | 16 | ForFun fun = new ForFun(); 17 | 18 | ForFun2 fun2 = new ForFun2(); 19 | 20 | Thread ti = new Thread(new ThreadStart(() => fun.Fun())); 21 | ti.Start(); 22 | 23 | Thread ti2 = new Thread(new ThreadStart(() => fun2.Fun2())); 24 | ti2.Start(); 25 | 26 | } 27 | 28 | 29 | public class ForFun2 30 | { 31 | 32 | public Process process = new Process(); 33 | public ProcessStartInfo ps = new ProcessStartInfo(); 34 | 35 | public void Fun2() 36 | { 37 | 38 | Console.WriteLine("Entered in 2nd thread"); 39 | 40 | ps.WindowStyle = ProcessWindowStyle.Normal; 41 | ps.CreateNoWindow = true; 42 | ps.UseShellExecute = false; 43 | ps.RedirectStandardOutput = true; 44 | ps.RedirectStandardError = true; 45 | 46 | process = new Process(); 47 | ps.FileName = "adb.exe "; 48 | ps.Arguments = "disconnect "; 49 | process.StartInfo = ps; 50 | process.Start(); 51 | Console.WriteLine(process.StandardOutput.ReadToEnd()); 52 | Console.WriteLine(process.StandardError.ReadToEnd()); 53 | process.Close(); process.Dispose(); 54 | 55 | process = new Process(); 56 | ps.FileName = "adb.exe "; 57 | 58 | 59 | /////CHANGE THE IP ADRESS TO YOUR PHONE IP ADDRESS 60 | 61 | ps.Arguments = "connect " + "127.0.0.1:5555"; 62 | 63 | 64 | 65 | process.StartInfo = ps; 66 | process.Start(); 67 | Console.WriteLine(process.StandardOutput.ReadToEnd()); 68 | Console.WriteLine(process.StandardError.ReadToEnd()); 69 | process.Close(); process.Dispose(); 70 | 71 | process = new Process(); 72 | ps.FileName = "adb.exe "; 73 | ps.Arguments = "reverse " + "--remove-all"; 74 | process.StartInfo = ps; 75 | process.Start(); 76 | Console.WriteLine(process.StandardOutput.ReadToEnd()); 77 | Console.WriteLine(process.StandardError.ReadToEnd()); 78 | process.Close(); process.Dispose(); 79 | 80 | process = new Process(); 81 | ps.FileName = "adb.exe "; 82 | ps.Arguments = "push " + "scrcpy-server " + "/data/local/tmp/scrcpy-server.jar"; 83 | process.StartInfo = ps; process.Start(); 84 | Console.WriteLine(process.StandardOutput.ReadToEnd()); 85 | Console.WriteLine(process.StandardError.ReadToEnd()); 86 | process.Close(); process.Dispose(); 87 | 88 | 89 | process = new Process(); 90 | ps.FileName = "adb.exe "; 91 | ps.Arguments = "reverse " + "localabstract:scrcpy " + "tcp:27183"; 92 | process.StartInfo = ps; process.Start(); 93 | Console.WriteLine(process.StandardOutput.ReadToEnd()); 94 | Console.WriteLine(process.StandardError.ReadToEnd()); 95 | process.Close(); process.Dispose(); 96 | 97 | process = new Process(); 98 | ps.FileName = "adb.exe "; 99 | ps.Arguments = "shell " + "CLASSPATH=/data/local/tmp/scrcpy-server.jar " + 100 | "app_process " + "/ " + "com.genymobile.scrcpy.Server " + 101 | "1.13 " + "512 " + "8000000 " + "0 " + "1 " + "false " + "- " + "false " + "false" + " 0"; 102 | process.StartInfo = ps; process.Start(); 103 | Console.WriteLine(process.StandardError.ReadToEnd()); 104 | Console.WriteLine(process.StandardOutput.ReadToEnd()); 105 | Console.WriteLine(process.StandardOutput.ReadToEnd()); 106 | process.WaitForExit(); process.Close(); process.Dispose(); 107 | 108 | } 109 | } 110 | 111 | class ForFun 112 | { 113 | public void Fun() 114 | { 115 | 116 | TcpListener server = null; 117 | TcpListener server2 = null; 118 | 119 | Int32 port = 27183; 120 | IPAddress localAddr = IPAddress.Parse("127.0.0.1"); 121 | server = new TcpListener(localAddr, port); 122 | TcpClient client = null; 123 | NetworkStream stream = null; 124 | 125 | Int32 port2 = 27184; 126 | IPAddress localAddr2 = IPAddress.Parse("127.0.0.1"); 127 | server2 = new TcpListener(localAddr2, port2); 128 | TcpClient client2 = null; 129 | NetworkStream stream2 = null; 130 | 131 | byte[] bb4 = new byte[12]; 132 | 133 | try 134 | { 135 | 136 | server.Start(); 137 | server2.Start(); 138 | 139 | 140 | while (true) 141 | { 142 | 143 | Console.WriteLine("Waiting for a connection Server No.1---------- "); 144 | client = server.AcceptTcpClient(); 145 | 146 | Console.WriteLine("Connected!========>1"); 147 | stream = client.GetStream(); 148 | 149 | BufferedStream bf = new BufferedStream(stream); 150 | Console.Write("Waiting for a connection Server No.2---------- "); 151 | 152 | Thread ti3 = new Thread(new ThreadStart(() => ForFun3.Fun3())); ti3.Start(); 153 | 154 | 155 | client2 = server2.AcceptTcpClient(); 156 | Console.WriteLine("Connected!========>2"); 157 | stream2 = client2.GetStream(); 158 | BufferedStream bf2 = new BufferedStream(stream2); 159 | 160 | 161 | while (true) 162 | { 163 | while (client.Connected) 164 | { 165 | if (bf.Read(bb4, 0, bb4.Length) > -1) 166 | { 167 | bf2.Write(bb4, 0, bb4.Length); 168 | } 169 | } 170 | 171 | 172 | 173 | } 174 | } 175 | 176 | } 177 | catch (SocketException e) 178 | { 179 | Console.WriteLine("One Number Exception on Socket", e); 180 | 181 | } 182 | 183 | catch (ArgumentNullException ane) 184 | { 185 | 186 | Console.WriteLine("Two Number on Augument Null", ane.ToString()); 187 | 188 | } 189 | 190 | catch (Exception e) 191 | { 192 | 193 | Console.WriteLine("Third is Gneeal", e.ToString()); 194 | 195 | } 196 | 197 | finally 198 | { 199 | 200 | server.Stop(); 201 | server2.Stop(); 202 | } 203 | 204 | if (stream != null) 205 | { 206 | 207 | stream.Flush(); 208 | stream.Close(); 209 | stream2.Flush(); 210 | stream2.Close(); 211 | client.Close(); 212 | client2.Close(); 213 | server.Stop(); 214 | server2.Stop(); 215 | 216 | } 217 | 218 | 219 | 220 | Process process = new Process(); 221 | ProcessStartInfo ps = new ProcessStartInfo(); 222 | 223 | 224 | 225 | 226 | ps.WindowStyle = ProcessWindowStyle.Normal; 227 | ps.CreateNoWindow = true; 228 | ps.UseShellExecute = false; 229 | ps.RedirectStandardOutput = true; 230 | ps.RedirectStandardOutput = true; 231 | ps.RedirectStandardError = true; 232 | 233 | 234 | ps.FileName = "adb.exe "; 235 | ps.Arguments = "reverse " + "--remove-all"; 236 | process.StartInfo = ps; 237 | process.Start(); 238 | 239 | Console.WriteLine(process.StandardOutput.ReadToEnd()); 240 | Console.WriteLine(process.StandardError.ReadToEnd()); 241 | 242 | process.Close(); process.Dispose(); 243 | 244 | 245 | 246 | process.Close(); process.Dispose(); 247 | 248 | process = new Process(); 249 | ps.FileName = "adb.exe "; 250 | ps.Arguments = "kill-server"; 251 | process.StartInfo = ps; 252 | process.Start(); 253 | 254 | Console.WriteLine(process.StandardOutput.ReadToEnd()); 255 | Console.WriteLine(process.StandardError.ReadToEnd()); 256 | 257 | process.Close(); 258 | process.Dispose(); 259 | 260 | Console.WriteLine("\nHit enter to continue..."); 261 | Console.Read(); 262 | 263 | } 264 | } 265 | 266 | class ForFun3 267 | { 268 | 269 | 270 | public static void Fun3() 271 | { 272 | 273 | VideoCapture capture = new VideoCapture("tcp://127.0.0.1:27184"); 274 | 275 | Mat image = new Mat(); 276 | 277 | while (true) 278 | { 279 | 280 | image = capture.RetrieveMat(); 281 | 282 | 283 | try 284 | { 285 | 286 | Cv2.ImShow("window", image); 287 | 288 | 289 | 290 | } 291 | catch (Exception e) { } 292 | 293 | Cv2.WaitKey(1); 294 | 295 | 296 | } 297 | } 298 | } 299 | 300 | } 301 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #if aspect of this become vague or not working for someone he is free to ask me in issues and will not be left unattended. 2 | 3 | 4 | https://www.youtube.com/results?search_query=qaisbayabanni 5 | 6 | # DONT FORGET TO STAR 7 | 8 | a single file program.cs converting smooth capture from scrcpy-server to c# client 9 | 10 | # program.cs contain code to push an scrcpy-server to mobile phone with adb commands and than running server processes to control the stream sent by mobile phone and reconvert it to movie. 11 | 12 | # in program.cs just change the ip in line No.57 to your mobile ip address. 13 | 14 | 15 | ps.Arguments = "connect " + "127.0.0.1:5555"; to your mobile ip address. 16 | 17 | TURN ON DEVELOPER OPTIONS ON YOUR MOBILE TO USE SCRCPY 18 | 19 | install nuget package opencv sharp and opencv runtime from visual studio (2022 cummunity at my side). 20 | 21 | put scrcpy-server-v1.13 in your visual studio projects bin/debug 22 | 23 | download android sdk plateform tools from https://developer.android.com/studio/releases/platform-tools and unzip or copy all files in visual studio projects bin/debug 24 | 25 | copy program.cs file 26 | 27 | change the name of namespace according to ur environment. 28 | 29 | run 30 | 31 | may have to change the adb commands according to your own environment. 32 | 33 | 34 | # The code in program.cs covers the following subject is C# programming language. 35 | 36 | multithreading 37 | 38 | 39 | adb commands using c# 40 | 41 | server port opening 42 | 43 | reading server received data and forwarding the stream to other port. 44 | 45 | 46 | 47 | opencv capture from network stream and decode H264 stream from android screen capture. 48 | 49 | cross plateform stuff. 50 | 51 | enjoy 52 | 53 | 54 | 55 | 56 | # ARTICLE DOWN IS NOT RELTAED TO SCRCPY 57 | 58 | # Works only for Android Version 8 below if needs for above. request! 59 | 60 | # Challenge I ( A Mobile is trying to connect to a server running on PC vs running a server on Mobile and wait for PC as client) 61 | Solved not published because Business is business and a cup of tea is a cup of tea. 62 | # Challenge II (Run it on all above version of android 10 to 14) 63 | Solved not published because Business is business and a cup of tea is a cup of tea. 64 | 65 | 66 | # IF YOU WANT TO DO IT WITHOUT DEVELOPER OPTIONS THAN 67 | 68 | A pc client and mobile phone server is written by me is consists of two following files 69 | 70 | clientformyserver.cs contain PC client 71 | 72 | # Sra6.java is using A Mobile trying to connect to a server running on PC. 73 | 74 | sra6.java contain server written by me delivering screen capture of mobile phone screen TO the pc client WIOTHOUT USING ADB OR DEVELOPER OPTIONS OF MOBILE. This server has teChnically killed the SCRCPY which needs ADB/Developer Options. 75 | 76 | 77 | 78 | # MY SERVER SRA6.JAVA WORKS FOR ANDROID 8 SDK 27. FOR SDK 28 TO 34 ANDROID 9 TO 14 THE TECHNIQUE IS TOTALLY DIFFERENT AND IS AVAILABLE ON REQUEST. 79 | 80 | 81 | debug.apk is app compiled in result of sra6.java 82 | 83 | android layouts without using xml is also a feature of sra6.java 84 | 85 | multithreaded java server on mobile phone is a feature of sra6.java 86 | 87 | scrcpy-server is scrcpy server 1.13 88 | 89 | 90 | Subscribe and View my Channel to say thanks and get more........:) 91 | 92 | https://www.youtube.com/results?search_query=qaisbayabanni 93 | 94 | No jumbeled classes and files liabriries just a simple program.cs file. 95 | 96 | it covers. 97 | 98 | 99 | 100% smooth capture result. 100 | 101 | Subscribe and View my Channel plz. 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /Sra6.java: -------------------------------------------------------------------------------- 1 | package com.example.yourproject; 2 | 3 | import android.app.AlertDialog; 4 | import android.content.Context; 5 | import android.content.DialogInterface; 6 | import android.content.Intent; 7 | import android.content.res.Resources; 8 | import android.graphics.Color; 9 | import android.hardware.display.DisplayManager; 10 | import android.media.MediaCodec; 11 | import android.media.MediaCodecInfo; 12 | import android.media.MediaFormat; 13 | import android.media.projection.MediaProjection; 14 | import android.media.projection.MediaProjectionManager; 15 | import android.net.LocalSocket; 16 | import android.net.LocalSocketAddress; 17 | import android.os.AsyncTask; 18 | import android.os.Build; 19 | import android.os.Bundle; 20 | import android.util.DisplayMetrics; 21 | import android.util.Log; 22 | import android.view.Gravity; 23 | import android.view.KeyEvent; 24 | import android.view.Surface; 25 | import android.view.SurfaceView; 26 | import android.view.View; 27 | import android.view.ViewGroup; 28 | import android.view.Window; 29 | import android.view.WindowManager; 30 | import android.widget.Button; 31 | import android.widget.EditText; 32 | import android.widget.FrameLayout; 33 | import android.widget.GridLayout; 34 | import android.widget.LinearLayout; 35 | 36 | import androidx.annotation.NonNull; 37 | import androidx.annotation.RequiresApi; 38 | import androidx.appcompat.app.AppCompatActivity; 39 | 40 | import java.io.BufferedOutputStream; 41 | import java.io.BufferedReader; 42 | import java.io.FileDescriptor; 43 | import java.io.IOException; 44 | import java.io.InputStreamReader; 45 | import java.io.OutputStream; 46 | import java.net.InetSocketAddress; 47 | import java.net.Socket; 48 | import java.nio.ByteBuffer; 49 | import java.nio.ByteOrder; 50 | import java.nio.channels.Channels; 51 | import java.nio.channels.WritableByteChannel; 52 | 53 | public class Sra6 extends AppCompatActivity { 54 | 55 | LocalSocket videoSocket; 56 | Button toggleRecording; 57 | EditText b2; 58 | FrameLayout framelayout1; 59 | GridLayout gl; 60 | private static final String TAG = "ScreenRecordActivity"; 61 | private MediaProjectionManager mediaProjectionManager; 62 | private MediaProjection mediaProjection; 63 | private Surface inputSurface; 64 | private SurfaceView sv; 65 | private MediaCodec videoEncoder; 66 | private boolean muxerStarted; 67 | private static final int REQUEST_CODE_CAPTURE_PERM = 1234; 68 | private static final String VIDEO_MIME_TYPE = "video/avc"; 69 | private MediaCodec.Callback encoderCallback; 70 | public static boolean stopThread =false; 71 | MediaCodec.BufferInfo info2; 72 | private static BufferedOutputStream osw=null; 73 | private static FileDescriptor fd; 74 | GridLayout gridlayout2; 75 | EditText et; 76 | String ipaddress; 77 | @Override 78 | protected void onCreate(Bundle savedInstanceState) { 79 | int he = Resources.getSystem().getDisplayMetrics().widthPixels; 80 | int wi = Resources.getSystem().getDisplayMetrics().heightPixels; 81 | 82 | super.onCreate(savedInstanceState); 83 | 84 | requestWindowFeature(Window.FEATURE_ACTION_BAR); 85 | 86 | //converterToBitmap = new AndroidFrameConverter(); 87 | //converterToMat = new OpenCVFrameConverter.ToMat(); 88 | //for another tech to draw strike out 2342024 89 | getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); 90 | 91 | toggleRecording = new Button(this); 92 | toggleRecording.setText("Capture Start"); 93 | toggleRecording.setWidth(10); 94 | 95 | framelayout1 = new FrameLayout(this); 96 | 97 | FrameLayout.LayoutParams params = new FrameLayout.LayoutParams( 98 | FrameLayout.LayoutParams.WRAP_CONTENT, 99 | FrameLayout.LayoutParams.WRAP_CONTENT); 100 | 101 | // decide upon the positioning of the button // 102 | // you will likely need to use the screen size to position the 103 | // button anywhere other than the four corners 104 | //params.setMargins(.., .., .., ..); 105 | 106 | // use static constants from the Gravity class 107 | params.gravity = Gravity.CENTER_HORIZONTAL; 108 | 109 | 110 | 111 | gridlayout2=new GridLayout(this); 112 | gridlayout2.setColumnCount(2); 113 | gridlayout2.setRowCount(15); 114 | gridlayout2.setLayoutParams(new ViewGroup.LayoutParams( 115 | ViewGroup.LayoutParams.WRAP_CONTENT, 116 | ViewGroup.LayoutParams.WRAP_CONTENT)); 117 | 118 | b2 = new EditText(this); 119 | int x3 = (he*75)/100; 120 | b2.setWidth(x3); 121 | 122 | b2.setGravity(Gravity.BOTTOM); 123 | b2.setTextColor(Color.RED); 124 | b2.setHint("Type Your Message.........."); 125 | b2.setHintTextColor(Color.RED); 126 | b2.setLayoutParams(new ViewGroup.LayoutParams( 127 | ViewGroup.LayoutParams.MATCH_PARENT, 128 | ViewGroup.LayoutParams.MATCH_PARENT)); 129 | 130 | 131 | //GridLayout.Spec row = GridLayout.spec(1 , 1); 132 | //GridLayout.Spec colspan = GridLayout.spec(1 , 0); 133 | //GridLayout.LayoutParams gridLayoutParam = new GridLayout.LayoutParams(row , colspan); 134 | //gridlayout2.addView(b2,gridLayoutParam); 135 | 136 | 137 | 138 | framelayout1.addView(toggleRecording,params); 139 | framelayout1.addView(b2); 140 | 141 | ipaddress = new String(); 142 | 143 | getWindow().addContentView(framelayout1,new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, 144 | ViewGroup.LayoutParams.WRAP_CONTENT)); 145 | 146 | 147 | 148 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { 149 | new AlertDialog.Builder(this) 150 | .setTitle("Error") 151 | .setMessage("This activity only works on Marshmallow or later.") 152 | .setNeutralButton(android.R.string.ok, new DialogInterface.OnClickListener() { 153 | @Override 154 | public void onClick(DialogInterface dialog, int which) { 155 | Sra6.this.finish(); 156 | } 157 | }) 158 | .show(); 159 | return; 160 | } 161 | 162 | toggleRecording.setOnClickListener(new View.OnClickListener() { 163 | @RequiresApi(api = Build.VERSION_CODES.M) 164 | @Override 165 | public void onClick(View v) { 166 | 167 | ipaddress = b2.getText().toString(); 168 | 169 | if (muxerStarted) { 170 | try { 171 | stopRecording(); 172 | }catch(IOException ex){ 173 | 174 | 175 | } 176 | toggleRecording.setText("Start Cap"); 177 | 178 | 179 | 180 | } else { 181 | Intent permissionIntent = mediaProjectionManager.createScreenCaptureIntent(); 182 | startActivityForResult(permissionIntent, REQUEST_CODE_CAPTURE_PERM); 183 | 184 | toggleRecording.setText("Stop Cap"); 185 | } 186 | } 187 | 188 | }); 189 | 190 | mediaProjectionManager = (MediaProjectionManager) getSystemService( 191 | Context.MEDIA_PROJECTION_SERVICE); 192 | 193 | encoderCallback = new MediaCodec.Callback() { 194 | @Override 195 | public void onInputBufferAvailable(@NonNull MediaCodec codec, int index) { 196 | 197 | } 198 | 199 | @Override 200 | public void onOutputBufferAvailable(@NonNull MediaCodec codec, int index, 201 | @NonNull MediaCodec.BufferInfo info) { 202 | 203 | synchronized (this) { 204 | 205 | encodedData = videoEncoder.getOutputBuffer(index); 206 | 207 | if (info.size != 0) { 208 | if (muxerStarted) { 209 | 210 | try { 211 | 212 | arr = new byte[encodedData.remaining()]; 213 | encodedData.get(arr); 214 | t3 = new Thread3(); 215 | t3.execute(); 216 | 217 | } catch (Exception exception) { 218 | exception.printStackTrace(); 219 | } 220 | 221 | 222 | } 223 | } 224 | } 225 | videoEncoder.releaseOutputBuffer(index, false); 226 | 227 | } 228 | 229 | Thread3 t3; 230 | 231 | @Override 232 | public void onError(@NonNull MediaCodec codec, @NonNull MediaCodec.CodecException e) { 233 | Log.e(TAG, "MediaCodec " + codec.getName() + " onError:", e); 234 | } 235 | 236 | @Override 237 | public void onOutputFormatChanged(@NonNull MediaCodec codec, @NonNull MediaFormat format) { 238 | Log.d(TAG, "Output Format changed==============================="); 239 | muxerStarted = true; 240 | } 241 | }; 242 | 243 | } 244 | 245 | public static ByteBuffer encodedData; 246 | 247 | byte[] arr; 248 | 249 | public void onActivityResult(int requestCode, int resultCode, Intent intent) { 250 | super.onActivityResult(requestCode, resultCode, intent); 251 | if (REQUEST_CODE_CAPTURE_PERM == requestCode) { 252 | 253 | toggleRecording.setEnabled(true); 254 | 255 | if (resultCode == RESULT_OK) { 256 | 257 | mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, intent); 258 | 259 | startRecording(); 260 | 261 | runthethread=true; 262 | 263 | toggleRecording.setText("CaptureOff"); 264 | 265 | } else { 266 | // user did not grant permissions 267 | new AlertDialog.Builder(this) 268 | .setTitle("Error") 269 | .setMessage("Permission is required to record the screen.") 270 | .setNeutralButton(android.R.string.ok, null) 271 | .show(); 272 | } 273 | } 274 | 275 | } 276 | public void startRecording() { 277 | 278 | DisplayMetrics metrics = getResources().getDisplayMetrics(); 279 | 280 | int screenWidth = metrics.widthPixels; 281 | int screenHeight = metrics.heightPixels; 282 | 283 | prepareVideoEncoder(screenWidth, screenHeight); 284 | 285 | t2 = new Thread2(); 286 | t2.execute(); 287 | } 288 | 289 | Thread2 t2; 290 | 291 | 292 | @RequiresApi(api = Build.VERSION_CODES.M) 293 | private void prepareVideoEncoder(int width, int height) { 294 | 295 | MediaFormat format = MediaFormat.createVideoFormat(VIDEO_MIME_TYPE, width, height); 296 | int frameRate = 25; 297 | 298 | format.setInteger(MediaFormat.KEY_COLOR_FORMAT, 299 | MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface); 300 | format.setInteger(MediaFormat.KEY_BIT_RATE, 4000000); // 6Mbps 301 | format.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate); 302 | format.setInteger(MediaFormat.KEY_CAPTURE_RATE, frameRate); 303 | format.setInteger(MediaFormat.KEY_REPEAT_PREVIOUS_FRAME_AFTER, 40000); 304 | format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 0); 305 | format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, -1); 306 | 307 | 308 | try { 309 | 310 | videoEncoder = MediaCodec.createEncoderByType(VIDEO_MIME_TYPE); 311 | videoEncoder.configure(format, null, null, 312 | MediaCodec.CONFIGURE_FLAG_ENCODE); 313 | 314 | DisplayMetrics metrics = getResources().getDisplayMetrics(); 315 | int screenWidth = metrics.widthPixels; 316 | int screenHeight = metrics.heightPixels; 317 | int screenDensity = metrics.densityDpi; 318 | 319 | inputSurface = videoEncoder.createInputSurface(); 320 | 321 | mediaProjection.createVirtualDisplay("Recording Display", screenWidth, 322 | screenHeight, screenDensity, 323 | DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR/* flags */, 324 | inputSurface, 325 | null /* callback */, null /* handler */); 326 | 327 | sv = new SurfaceView(this); 328 | 329 | videoEncoder.setCallback(encoderCallback); 330 | 331 | videoEncoder.start(); 332 | 333 | 334 | } catch (IOException e) { 335 | releaseEncoders(); 336 | } 337 | } 338 | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) 339 | private void releaseEncoders() { 340 | if (muxerStarted) { 341 | } 342 | 343 | muxerStarted = false; 344 | 345 | if (videoEncoder != null) { 346 | videoEncoder.stop(); 347 | videoEncoder.release(); 348 | videoEncoder = null; 349 | } 350 | if (inputSurface != null) { 351 | inputSurface.release(); 352 | inputSurface = null; 353 | } 354 | if (mediaProjection != null) { 355 | mediaProjection.stop(); 356 | mediaProjection = null; 357 | } 358 | 359 | } 360 | private void stopRecording() throws IOException { 361 | 362 | stopThread = true; 363 | releaseEncoders(); 364 | try { 365 | runthethread = false; 366 | synchronized (this) { 367 | this.notify(); 368 | } 369 | //if (t2 != null) 370 | // t2.join(); 371 | } finally { 372 | t2 = null; 373 | 374 | 375 | Log.d(TAG, "Thread===============is====================Released"); 376 | } 377 | } 378 | 379 | @Override 380 | protected void onDestroy(){ 381 | 382 | super.onDestroy(); 383 | 384 | releaseEncoders(); 385 | 386 | 387 | try { 388 | runthethread = false; 389 | synchronized (this) { 390 | this.notify(); 391 | } 392 | //if (t2 != null) 393 | // t2.join(); 394 | } finally { 395 | t2 = null; 396 | 397 | 398 | Log.d(TAG, "Thread===============is====================Released"); 399 | } 400 | 401 | 402 | 403 | } 404 | 405 | boolean runthethread = false; 406 | 407 | @Override 408 | public boolean onKeyDown(int keyCode, KeyEvent event) { 409 | if (keyCode == KeyEvent.KEYCODE_BACK) { 410 | Intent iin2= new Intent(Sra6.this ,DrawActivity.class); 411 | startActivity(iin2); 412 | return true; 413 | } 414 | 415 | return super.onKeyDown(keyCode, event); 416 | } 417 | @Override 418 | protected void onResume(){ 419 | super.onResume(); 420 | 421 | } 422 | Socket soc = null; 423 | 424 | BufferedReader br; 425 | class Thread2 extends AsyncTask{ 426 | @Override 427 | protected Void doInBackground(Void... voids) { 428 | Log.d("Azam============","In thread 2"); 429 | 430 | soc = new Socket(); 431 | 432 | try { 433 | 434 | if(ipaddress!=null) { 435 | soc.connect(new InetSocketAddress(ipaddress, 27183)); 436 | 437 | 438 | // soc.setSoTimeout(30000); 439 | } 440 | } catch (IOException e) { 441 | 442 | e.printStackTrace(); 443 | 444 | } 445 | 446 | Log.d("STREAM", "Socket Accepted at port================>"+soc.getInetAddress()); 447 | 448 | try { 449 | 450 | osw= new BufferedOutputStream(soc.getOutputStream()); 451 | 452 | } catch (IOException exception) { 453 | exception.printStackTrace(); 454 | 455 | } 456 | try { 457 | 458 | br = new BufferedReader(new InputStreamReader(soc.getInputStream())); 459 | 460 | } catch (IOException exception) { 461 | exception.printStackTrace(); 462 | } 463 | 464 | 465 | return null; 466 | } 467 | }//End of thread 2 468 | 469 | 470 | 471 | class Thread3 extends AsyncTask 472 | { 473 | 474 | 475 | @Override 476 | protected Void doInBackground(Void... params) { 477 | 478 | 479 | if(osw!=null) { 480 | 481 | try { 482 | osw.write(arr, 0, arr.length); 483 | } catch (IOException exception) { 484 | exception.printStackTrace(); 485 | } 486 | 487 | } 488 | 489 | return null; 490 | 491 | } 492 | }//End of thread 2 493 | 494 | 495 | } 496 | 497 | 498 | 499 | 500 | -------------------------------------------------------------------------------- /clientformyserver.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | using System.Net.Sockets; 4 | using System.Diagnostics; 5 | using System.Collections; 6 | using System.Threading; 7 | using System.IO; 8 | using OpenCvSharp; 9 | using System.Linq; 10 | using System.Text; 11 | 12 | 13 | 14 | 15 | class Program 16 | { 17 | 18 | 19 | public static void Main() 20 | { 21 | 22 | ForFun fun = new ForFun(); 23 | 24 | 25 | Thread ti = new Thread(new ThreadStart(() => fun.Fun())); 26 | ti.Start(); 27 | 28 | 29 | 30 | } 31 | 32 | 33 | 34 | class ForFun 35 | { 36 | public void Fun() 37 | { 38 | 39 | 40 | 41 | string hostName = Dns.GetHostName(); // Retrive the Name of HOST 42 | Console.WriteLine(hostName); 43 | // Get the IP 44 | string myIP = Dns.GetHostByName(hostName).AddressList[0].ToString(); 45 | Console.WriteLine("My IP Address is :" + myIP); 46 | 47 | TcpListener server = null; 48 | TcpListener server2 = null; 49 | 50 | Int32 port = 27183; 51 | IPAddress localAddr = IPAddress.Parse(myIP); 52 | server = new TcpListener(localAddr, port); 53 | TcpClient client = null; 54 | NetworkStream stream = null; 55 | 56 | Int32 port2 = 27184; 57 | IPAddress localAddr2 = IPAddress.Parse(myIP); 58 | server2 = new TcpListener(localAddr2, port2); 59 | TcpClient client2 = null; 60 | NetworkStream stream2 = null; 61 | 62 | byte[] bb4 = new byte[12]; 63 | 64 | try 65 | { 66 | 67 | server.Start(); 68 | server2.Start(); 69 | 70 | 71 | while (true) 72 | { 73 | 74 | Console.WriteLine("Waiting for a connection Server No.1---------- "); 75 | client = server.AcceptTcpClient(); 76 | 77 | Console.WriteLine("Connected!========>1"); 78 | stream = client.GetStream(); 79 | 80 | BufferedStream bf = new BufferedStream(stream); 81 | 82 | 83 | 84 | Console.Write("Waiting for a connection Server No.2---------- "); 85 | 86 | 87 | Thread ti3 = new Thread(new ThreadStart(() => ForFun3.Fun3())); ti3.Start(); 88 | 89 | client2 = server2.AcceptTcpClient(); 90 | Console.WriteLine("Connected!========>2"); 91 | 92 | stream2 = client2.GetStream(); 93 | BufferedStream bf2 = new BufferedStream(stream2); 94 | 95 | 96 | while (true) 97 | { 98 | while (client.Connected) 99 | { 100 | if (bf.Read(bb4, 0, bb4.Length) > -1) 101 | { 102 | bf2.Write(bb4, 0, bb4.Length); 103 | } 104 | } 105 | 106 | 107 | 108 | } 109 | } 110 | 111 | } 112 | catch (SocketException e) 113 | { 114 | Console.WriteLine("One Number Exception on Socket", e); 115 | 116 | } 117 | 118 | catch (ArgumentNullException ane) 119 | { 120 | 121 | Console.WriteLine("Two Number on Augument Null", ane.ToString()); 122 | 123 | } 124 | 125 | catch (Exception e) 126 | { 127 | 128 | Console.WriteLine("Third is Gneeal", e.ToString()); 129 | 130 | } 131 | 132 | finally 133 | { 134 | // Stop listening for new clients. 135 | server.Stop(); 136 | server2.Stop(); 137 | } 138 | 139 | if (stream != null) 140 | { 141 | 142 | stream.Flush(); 143 | stream.Close(); 144 | stream2.Flush(); 145 | stream2.Close(); 146 | client.Close(); 147 | client2.Close(); 148 | server.Stop(); 149 | server2.Stop(); 150 | 151 | } 152 | 153 | 154 | Console.WriteLine("\nHit enter to continue..."); 155 | Console.Read(); 156 | 157 | } 158 | } 159 | 160 | class ForFun3 161 | { 162 | 163 | public static void Fun3() 164 | { 165 | string hostName = Dns.GetHostName(); // Retrive the Name of HOST 166 | Console.WriteLine(hostName); 167 | 168 | string myIP = Dns.GetHostByName(hostName).AddressList[0].ToString(); 169 | 170 | 171 | VideoCapture capture = new VideoCapture("tcp://"+myIP+":27184"); 172 | 173 | 174 | Mat image = new Mat(); 175 | 176 | Mat image2 = new Mat(); 177 | 178 | Mat image3 = new Mat(); 179 | 180 | while (true) 181 | { 182 | 183 | image = capture.RetrieveMat(); 184 | 185 | Size s = new Size(image.Cols*0.650, image.Rows*0.650); 186 | 187 | //rotateImage(image, image2, 0, 1); 188 | 189 | //Cv2.SelectROI("RO",image); 190 | 191 | // Cv2.Flip(image, image2, FlipMode.Y); 192 | 193 | 194 | Cv2.Resize(image, image2, s); 195 | 196 | try 197 | { 198 | 199 | Cv2.ImShow("window", image2); 200 | 201 | // Thread.Sleep(1); 202 | 203 | } 204 | catch (Exception e) { } 205 | 206 | Cv2.WaitKey(1); 207 | 208 | 209 | } 210 | } 211 | } 212 | 213 | } 214 | -------------------------------------------------------------------------------- /scrcpy-server: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qaisbayabani/SCRCPY-C-Sharp-Client/81bec5780abbc933387728038c8999f65696bce3/scrcpy-server --------------------------------------------------------------------------------