• android遥控器:控制电脑上的暴风影音播放(C#作为服务端)


    源码:点此下载

    不知道大家有没有和我一样的习惯,喜欢躺在床上看电影,手里还拿着手机玩。。。

    所以我就想到了这样一个程序:用android手机控制电脑上的暴风影音播放(当然,同样的方法也适用于pps什么的)。大冷天的,来电话需要暂停电影电视的播放,只要在被窝里轻轻一晃手机,就停止播放了,感觉还是挺爽的,哈哈。

    首先讲一下手机和电脑的互联:

    1,家里有无线网路由器的话,直接将手机介入无线网就可以了。

    2,只有手机和笔记本的话,可以打开android的wifi热点。设置-无线和网络-绑定与便携式热点,打开便携式热点。然后用笔记本连接。这里要注意一下,笔记本自动获取ip的话,就可以通过android上网了,想阻止笔记本联网(省流量),可以看下笔记本自动获取到的ip和掩码,然后将ip改为手动设置,填入刚才自动获取的ip和掩码,注意千万不要设置网关和dns,不然你就等着流量耗完泪奔吧。

    下面是实现原理:

      播放器都有自己的快捷键,比如暴风:空格键是暂停,ctrl+left是快退,ctrl+right是快进。所以我就想到了用PostMessage方法向(本来是用SendMessage的,可是不管用,后来改成PostMessage后就好了--//)暴风影音窗口发送键盘消息。所以要在电脑上用C#写一个程序,用来接收android手机的消息,然后使用PostMessage方法来控制暴风影音。无论暴风影音最小化还是全屏播放都是可以接收到消息的。

    下面是实现方法:

    一,首先是电脑上的C#监听程序,首先新建一个SendMsg类,实现向暴风影音发送消息。

    其中向键盘发送的消息,我使用了spy++来不作的,不知道使用的google一下。其中碰到了一个问题,无法使用postMessage向进程发送“Ctrl+left”组合键,网上查了一下也说不可以,希望知道的朋友写一下方法。所以我就在暴风影音里修改了一下快捷键,将快进和快退功能分别变为right和left。

    实现播放暂停的代码片段:

     /// <summary>
    /// 开始,暂停
    /// </summary>
    public void StartOrStop()
    {
    PostMessage(mainWindowHander, 0x0100, 0x20, 0x20390001);
    PostMessage(mainWindowHander, 0x0101, 0x20, 0x20390001);
    }

    PostMessage中0x20390001代表空格键。PostMessage发动键盘消息的使用可以参考C#中使用 SendMessage 向非顶端窗体发送组合键

    上面的这个方法模拟在暴风影音上按下,松开空格键。

    下面是控制暴风影音的代码:

     1 using System;
    2 using System.Runtime.InteropServices;
    3 using System.Diagnostics;
    4 using System.Threading;
    5
    6 namespace 暴风control
    7 {
    8 public class SendMsg
    9 {
    10 [DllImport("user32.dll", EntryPoint = "PostMessage")]  //使用系统的非托管代码。
    11 public static extern int PostMessage(
    12 IntPtr hwnd,
    13 int wMsg,
    14 uint wParam,
    15 uint lParam
    16 );
    17
    18 IntPtr mainWindowHander;
    19
    20 /// <summary>
    21 /// 遍历电脑所有的进程,获取暴风影音句柄
    22 /// </summary>
    23 public SendMsg()
    24 {
    25 Process[] allProcesses = Process.GetProcesses();
    26 foreach (Process p in allProcesses)
    27 {
    28 if (p.ProcessName == "StormPlayer")  //最新版暴风的进程名是StormPlayer,以前的是Storm在任务管理器里可以看到,这里不一样要修改一下。
    29 mainWindowHander = p.MainWindowHandle;
    30 }
    31 if (mainWindowHander == IntPtr.Zero)
    32 {
    33 Process p = new Process();
    34 p.StartInfo.FileName = @"D:\Baofeng\StormPlayer\StormPlayer.exe"; //暴风影音地址,改成你们自己的。
    35 p.Start();
    36 Thread.Sleep(3000);  //这里是笨方法,要等待3秒,以免暴风影音进程还没有启动就获取句柄。
    37 mainWindowHander = p.MainWindowHandle;
    38 }
    39 }
    40
    41 /// <summary>
    42 /// 开始,暂停
    43 /// </summary>
    44 public void StartOrStop()
    45 {
    46 PostMessage(mainWindowHander, 0x0100, 0x20, 0x20390001);
    47 PostMessage(mainWindowHander, 0x0101, 0x20, 0x20390001);
    48 }
    49
    50 /// <summary>
    51 /// 快退
    52 /// </summary>
    53 public void Back()
    54 {
    55 PostMessage(mainWindowHander, 0x0100, 0x25, 0x204b0001);
    56 PostMessage(mainWindowHander, 0x0101, 0x25, 0x204b0001);
    57 }
    58
    59 /// <summary>
    60 /// 快进
    61 /// </summary>
    62 public void Qian()
    63 {
    64 PostMessage(mainWindowHander, 0x0100, 0x27, 0x204d0001);
    65 PostMessage(mainWindowHander, 0x0101, 0x27, 0x204d0001);
    66 }
    67 }
    68 }

    二,C#和android使用socket通信。

    C#服务端的代码:

    using System;
    using System.Text;
    using System.Net.Sockets;
    using System.Net;
    using System.Threading;
    using System.Windows.Forms;

    namespace 暴风control
    {
    class NetControl
    {
    SendMsg sendMsg = new SendMsg();
    TextBox textBox;

    public NetControl(TextBox tmpTextBox)
    {
    textBox = tmpTextBox;
    }

    public void BeginListen()
    {
    Thread.CurrentThread.IsBackground = true;
    TcpListener server = new TcpListener(IPAddress.Any, 12121);
    server.Start();
    while (true)
    {
    TcpClient client= server.AcceptTcpClient();
    Thread clientThread = new Thread(new ParameterizedThreadStart(receiveMsg));
    clientThread.Start(client);
    }
    }

    /// <summary>
    /// 服务器侦听
    /// </summary>
    /// <param name="result"></param>
    private void receiveMsg(Object obj)
    {
    Control.CheckForIllegalCrossThreadCalls = false;
    Thread.CurrentThread.IsBackground = true;
    using (TcpClient client =(TcpClient)obj)
    {
    using (NetworkStream stream = client.GetStream())
                    {
                        int dataLength = 0;
                        string str;
                        string msg;
                        do
                        {
                            byte[] buffer = new byte[32];
                            dataLength = stream.Read(buffer, 0, buffer.Length);
                            str = Encoding.ASCII.GetString(buffer, 0, dataLength);
                            msg = Encoding.ASCII.GetString(buffer);
                            sendMessage(msg);
                            textBox.Text += "\r\n" + msg + "\r\n-----";
                        } while (client.Connected && msg.Substring(0, 4)!="over");  //就受到over字符串就断开连接,否则会出现死循环。。。
                    }
    }
    }

    /// <summary>
    /// 根据收到信息,使用不同的功能(快进,暂停等)
    /// </summary>
    private void sendMessage(string msg)
    {
    string res=msg.Substring(0,4);
    switch (res)
    {
    case "back":
    sendMsg.Back();
    break;
    case "qian":
    sendMsg.Qian();
    break;
    case "stsp":
    sendMsg.StartOrStop();
    break;
    }
    }
    }
    }

    android端的socket相关代码(现学现用,大家见谅。。):

    package com.android.baofengControl;

    import java.io.BufferedWriter;
    import java.io.IOException;
    import java.io.OutputStreamWriter;
    import java.io.PrintWriter;
    import java.net.InetAddress;
    import java.net.Socket;
    import java.net.UnknownHostException;
    import android.content.Context;
    import android.widget.TextView;

    public class Client {
    Socket client;
    PrintWriter out;
    TextView txt;
    Context context;

    public Client(TextView txt,Context context)
    {
    this.txt=txt;
    this.context=context;
    }

    ///建立连接,并保持
    public void connectServer(String ip)
    {
    InetAddress serverAddress = null;
    try {
    serverAddress = InetAddress.getByName(ip);
    } catch (UnknownHostException e) {
    txt.setText(e.getLocalizedMessage()+txt.getText());
    e.printStackTrace();
    }

    try {
    client=new Socket(serverAddress,12121);
    out=new PrintWriter(new BufferedWriter(new OutputStreamWriter(client.getOutputStream())),true);
    } catch (IOException e) {
    txt.setText(e.getLocalizedMessage()+txt.getText());
    e.printStackTrace();
    }
    }

      //发送消息
    public void sendMsg(String msg) throws IOException
    {
    out.println(msg);
    }

      //发送over结束字符,然后断开连接
    public void close()
    {
    out.println("over");
    out.close();
    txt.setText("end"+txt.getText());
    }
    }


    三,摇晃手机控制播放

    这里使用了网上已有的代码,稍加修改。

    package com.android.baofengControl;

    import java.io.IOException;
    import android.hardware.Sensor;
    import android.hardware.SensorEvent;
    import android.hardware.SensorEventListener;
    import android.hardware.SensorManager;

    public class MySensor {
    SensorManager sensorManager;
    Client client;

    ///开始监听加速传感器
    public void Listen(SensorManager sensorManager,Client client)
    {
    this.client=client;  //发送联网数据的类。
    this.sensorManager=sensorManager;
    Sensor sensor=sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    sensorManager.registerListener(sensorEventListener, sensor, SensorManager.SENSOR_DELAY_NORMAL);
    }

    SensorEventListener sensorEventListener =new SensorEventListener(){

    long lastUpdate,lastShakeTime = 0;
    float x,y,last_x = 0,last_y = 0;
    static final int SHAKE_THRESHOLD = 750;

    public void onAccuracyChanged(android.hardware.Sensor arg0, int arg1) {
    // TODO Auto-generated method stub

    }

    public void onSensorChanged(SensorEvent e) {
    long curTime = System.currentTimeMillis();
    // detect per 100 Millis
    if ((curTime - lastUpdate) > 100) {
    long diffTime = (curTime - lastUpdate);
    lastUpdate = curTime;
    //这里做了简化,没有用z的数据
    x = e.values[SensorManager.DATA_X];
    y = e.values[SensorManager.DATA_Y];
    //z = Math.abs(values[SensorManager.DATA_Z]);
    float acceChangeRate = 0;// = Math.abs(x+y - last_x - last_y) / diffTime * 1000;
    if(last_x != 0) acceChangeRate = Math.abs(x+y - last_x - last_y) / diffTime * 10000;
    //这里设定2个阀值,一个是加速度的,一个是shake的间隔时间的
    if (acceChangeRate > SHAKE_THRESHOLD && curTime - lastShakeTime > 1000) {

    lastShakeTime = curTime;
    try {
    client.sendMsg("stsp"); //发送消息。。。。。。。。。。。。。。。
    } catch (IOException e1) {
    e1.printStackTrace();
    }
    }
    last_x = x;
    last_y = y;
    }
    }};
    }

    最后,运行程序,然后可以按home键隐藏,只要要一下手机就可以控制暴风了。我的是2.3.7系统,测试通过。

  • 相关阅读:
    博客是一种心情
    双显示器和双鼠标
    C++ Primer Plus 第六版 代码笔记
    Bug,昂首走进2005
    让万能五笔2004免费版改首页的功能见鬼去吧。
    Gmail提供POP3和SMTP已经老长时间了
    快过年回家了,发点实用的东西给大家
    关于博客园Post的时候排版的一点小建议
    在.Net下进行MicroStation(GG)的开发(一)
    验证域的另一方法
  • 原文地址:https://www.cnblogs.com/fmnisme/p/2363223.html
Copyright © 2020-2023  润新知