手机
端软件:SoundWire, https://soundwire.en.uptodown.com/
android
/download
电脑
端软件:SoundWire Server, https://soundwire-server.en.uptodown.com/windows/download
教程:https://tech.wmzhe.com/artic
旧
手机
再利用:Iriun WinWebcam软件旧
手机
也能当
电脑
摄像头
。
现在
手机
更新换代快,大家多多少少手里都有一个两个旧
手机
,扔了吧,还能用挺可惜,留着吧,又没什么用,实在是鸡肋至极。
但如果你恰好有需要一个
电脑
摄像头
+录音,那么今天这款Iriun WinWebcam软件就非常适合你,Iriun WinWebcam可以将
手机
模拟真实
摄像头
硬件,还支持有线/无线传输,顺带连
麦克风
功能
也支持了,非常不错,
实际生活中经常遇到要使用一个
摄像头
做多个事情的情况,但在开发中,一个
摄像头
只能被一个应用程序所占有,当一个应用程序在使用
摄像头
时,其他所有应用程序都无法在使用这个
摄像头
。怎么解决这个问题呢?其实可以采用虚拟
摄像头
技术。
从网上找的虚拟
摄像头
技术一个比较容易理解的框架图。
根据这个图很容易理解就是需要实现一个camera proxy,来实现把真实
摄像头
的数据时时放入虚拟
摄像头
。
以r...
今天大概是兴趣加技术篇,程序员不写点有趣的代码,怕是很难在女票和家人面前秀出科技感。GITHUB:github.com/
Android
Msky…
如GIF所示,自动接起QQ电话。
QQ视频来电自动接起来,微信视频电自动接起来。
首先你需要两个硬件设备1.一步Root了的,并且安装
手机
QQ的
安卓
手机
。2.如果像文档一点你可能需要一个
手机
支架。
两步逻辑很简单:1.通过BroadcastReceiv...
随着网络的普及,视频聊天很是必要
哪天临时需要视频,手头又没有准备
摄像头
,我们一般就只能放弃了
其实我们手头500W像素以上的
手机
比比皆是,难道
手机
摄像头
就无其他用武之地了么?
有些朋友可能会通过
手机
QQ和对方视频,那效果,不敢恭维。为何不用我们的
手机
充当
电脑
摄像头
呢?
......
不管是
安卓
用户还是苹果用户都可以嗷。
因为疫情好多人都网上面试,然后我发现一个问题:有的人
台式
机没
摄像头
,笔记本像素又差的一匹,那怎么办呢。所以我就机智地搜索了一下如何用
手机
做
电脑
摄像头
。
我发现网上一堆很老旧的教程,完全没几个能用的唉。所以我只好总结一下现在可行又简便的方法了。
文章目录不推荐 DroidCamXivCam无他相机
不推荐 DroidCamX
我看目前百度查找到的能用的也就Dro...
public int width = 1920;
public int height = 1080;
public string outputPath = "output.mp4";
private bool isRecording = false;
private float startTime;
private string tempPath;
void Start () {
tempPath = Path.Combine(Application.temporaryCachePath, "temp.mp4");
void Update () {
if (Input.GetKeyDown(KeyCode.R)) {
if (!isRecording) {
StartRecording();
} else {
StopRecording();
void StartRecording () {
isRecording = true;
startTime = Time.time;
Screen.SetResolution(width, height, false);
Application.targetFrameRate = frameRate;
Microphone.Start(null, true, 10, AudioSettings.outputSampleRate);
void StopRecording () {
isRecording = false;
Screen.SetResolution(Screen.currentResolution.width, Screen.currentResolution.height, true);
Application.targetFrameRate = -1;
Microphone.End(null);
StartCoroutine(EncodeVideo());
IEnumerator EncodeVideo () {
yield return new WaitForEndOfFrame();
var audioClip = Microphone.GetClip(null, false);
var videoEncoder = new VideoEncoder(tempPath, width, height, frameRate);
var audioEncoder = new AudioEncoder(tempPath, audioClip);
var videoThread = new System.Threading.Thread(videoEncoder.Encode);
var audioThread = new System.Threading.Thread(audioEncoder.Encode);
videoThread.Start();
audioThread.Start();
videoThread.Join();
audioThread.Join();
File.Move(tempPath, outputPath);
Debug.Log("Video saved to " + outputPath);
public class VideoEncoder {
private string outputPath;
private int width;
private int height;
private int frameRate;
public VideoEncoder (string outputPath, int width, int height, int frameRate) {
this.outputPath = outputPath;
this.width = width;
this.height = height;
this.frameRate = frameRate;
public void Encode () {
var args = string.Format("-y -f rawvideo -pix_fmt rgba -s {0}x{1} -r {2} -i - -c:v libx264 -preset ultrafast -crf 0 {3}", width, height, frameRate, outputPath);
var process = new System.Diagnostics.Process();
process.StartInfo.FileName = "ffmpeg";
process.StartInfo.Arguments = args;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.Start();
var stdin = process.StandardInput.BaseStream;
var stdout = process.StandardOutput.BaseStream;
var stderr = process.StandardError.BaseStream;
var buffer = new byte[width * height * 4];
while (true) {
var time = Time.time - startTime;
if (time < 0) {
continue;
var frame = Mathf.FloorToInt(time * frameRate);
if (frame >= 0 && frame < maxFrames) {
var rect = new Rect(0, 0, width, height);
var tex = new Texture2D(width, height, TextureFormat.RGBA32, false);
tex.ReadPixels(rect, 0, 0);
tex.Apply();
var pixels = tex.GetRawTextureData();
stdin.Write(pixels, 0, pixels.Length);
Destroy(tex);
} else if (frame >= maxFrames) {
break;
stdin.Close();
process.WaitForExit();
Debug.Log(process.StandardError.ReadToEnd());
public class AudioEncoder {
private string outputPath;
private AudioClip audioClip;
public AudioEncoder (string outputPath, AudioClip audioClip) {
this.outputPath = outputPath;
this.audioClip = audioClip;
public void Encode () {
var args = string.Format("-y -f s16le -ar {0} -ac 1 -i - -c:a aac -b:a 256k {1}", audioClip.frequency, outputPath);
var process = new System.Diagnostics.Process();
process.StartInfo.FileName = "ffmpeg";
process.StartInfo.Arguments = args;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.Start();
var stdin = process.StandardInput.BaseStream;
var stdout = process.StandardOutput.BaseStream;
var stderr = process.StandardError.BaseStream;
var buffer = new float[audioClip.samples * audioClip.channels];
audioClip.GetData(buffer, 0);
var bytes = new byte[buffer.Length * 2];
for (int i = 0; i < buffer.Length; i++) {
var sample = Mathf.Clamp01(buffer[i]);
var value = (short)(sample * 32767);
bytes[i * 2] = (byte)(value & 0xff);
bytes[i * 2 + 1] = (byte)(value >> 8);
stdin.Write(bytes, 0, bytes.Length);
stdin.Close();
process.WaitForExit();
Debug.Log(process.StandardError.ReadToEnd());
这个脚本使用了ffmpeg来编码视频和音频,需要在系统中安装ffmpeg并将其添加到环境变量中。录制视频时,可以按下R键开始/停止录制,录制完成后会保存为一个MP4文件。