win11实时字幕,显示到在线视频

10 篇文章 1 订阅
7 篇文章 0 订阅

妈妈再也不用担心我找不到字幕了


win11自带了一个实时字幕,识别效果还不错

于是我就有了个想法,抓取文本并,通过网络本地调用,然后实时加载到在线视频上。

说干就干,一开始我尝试使用node,flutter都失败了。

于是我就只能被迫使用了我从未用过的C#

万万没想到,我的第一个C#程序不是helloworld

using System;
using System.Collections.Generic;
using System.Windows.Automation;

class Program
{
    static void Main(string[] args)
    {
        string windowTitle;
        if (args.Length == 0)
        {
            windowTitle = "实时辅助字幕";
            Console.WriteLine("Usage: uiget.exe \"Window Title\"");
            //return;
        }
        else
        {

        windowTitle = args[0];
        }

        // 查找具有特定标题的窗口
        AutomationElement window = FindWindowByTitle(windowTitle);

        if (window != null)
        {

            List<string> texts = new List<string>();
            WalkAutomationTreeAndCollectTexts(window, texts);
            Console.WriteLine(texts[0]);
        }
        else
        {
            Console.WriteLine("");
        }
    }

    static AutomationElement FindWindowByTitle(string title)
    {
        var condition = new PropertyCondition(AutomationElement.NameProperty, title);
        return AutomationElement.RootElement.FindFirst(TreeScope.Children, condition);
    }

    static void WalkAutomationTree(AutomationElement rootElement)
    {
        var condition = Condition.TrueCondition; // 查找所有子节点
        var treeWalker = new TreeWalker(condition);
        WalkAutomationTree(treeWalker, rootElement, 0);
    }

    // 递归遍历UI自动化树
    static void WalkAutomationTree(TreeWalker walker, AutomationElement element, int indent)
    {
        string indentString = new string(' ', indent);

        // 尝试使用ObjectModel获取文本
        string elementText = GetTextFromElement(element);
        Console.WriteLine($"{indentString}{element.Current.ControlType.ProgrammaticName} - Name: {element.Current.Name}, Text: {elementText}");

        AutomationElement child = walker.GetFirstChild(element);
        while (child != null)
        {
            WalkAutomationTree(walker, child, indent + 2); // 增加缩进
            child = walker.GetNextSibling(child); // 移动到下一个兄弟元素
        }
    }

    // 从元素获取文本的尝试
    static string GetTextFromElement(AutomationElement element)
    {
        try
        {
            object patternObj;
            if (element.TryGetCurrentPattern(TextPattern.Pattern, out patternObj))
            {
                var textPattern = (TextPattern)patternObj;
                return textPattern.DocumentRange.GetText(-1).TrimEnd('\r'); // 获取所有文本并删除尾随的回车符
            }
            else if (element.TryGetCurrentPattern(ValuePattern.Pattern, out patternObj))
            {
                var valuePattern = (ValuePattern)patternObj;
                return valuePattern.Current.Value;
            }
            else
            {
                // 没有找到TextPattern或ValuePattern
                return string.Empty;
            }
        }
        catch (ElementNotAvailableException)
        {
            return string.Empty;
        }
    }
    static void WalkAutomationTreeAndCollectTexts(AutomationElement element, List<string> texts)
    {
        var treeWalker = TreeWalker.RawViewWalker;
        CollectTextsRecursively(treeWalker, element, texts);
    }

    static void CollectTextsRecursively(TreeWalker walker, AutomationElement element, List<string> texts)
    {
        string elementText = GetTextFromElement(element);
        if (!string.IsNullOrEmpty(elementText))
        {
            texts.Add(elementText);
        }

        AutomationElement child = walker.GetFirstChild(element);
        while (child != null)
        {
            CollectTextsRecursively(walker, child, texts);
            child = walker.GetNextSibling(child);
        }
    }
}

然后再使用我熟悉的nodejs调用

const { exec } = require('child_process');
const iconv = require('iconv-lite');

function getUITextByTitle(title, callback) {
  exec(`uiget.exe "${title}"`, { encoding: 'buffer' }, (error, stdoutBuffer, stderrBuffer) => {
    console.log('当前Node.js默认编码:', Buffer.from('').constructor.name);
    if (error) {
      return callback(error, null);
    }
    if (stderrBuffer.length) {
      // 注意:这里假设标准错误流(stderr)也是 GB2312 编码
      return callback(new Error(iconv.decode(stderrBuffer, 'GB2312')), null);
    }

    try {
      // 使用iconv-lite将Buffer从GB2312转码为UTF-8字符串
      const stdoutText = iconv.decode(stdoutBuffer, 'GB2312');
      callback(null, stdoutText);
    } catch (parseError) {
      callback(parseError, null);
    }
  });
}

大功告成,之后就是封装为route,用express代理一下就好了
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值