将音频与视频结合(不使用 ffmpeg)- Java

2023-11-22

我正在构建一个小程序来捕获屏幕和麦克风输入(音频)。我可以单独录制这些文件,但找不到将这些文件组合起来制作新的音频视频的方法。

视频文件位于.mov格式和音频是.wav格式。它们的长度完全相同。

有什么办法可以合并这些文件吗?我尝试过 Java,但找不到合并两个文件的方法。

我也必须这样做而不ffmpeg因为它需要安装在客户端。


private void mergeFiles() {
    try {   
        DataSource videoDataSource = javax.media.Manager.createDataSource(oml.getURL()); //your video file
        DataSource audioDataSource = javax.media.Manager.createDataSource(realAudioFile.toURI().toURL()); // your audio file
        DataSource mixedDataSource = null; // data source to combine video with audio
        DataSource arrayDataSource[] = new DataSource[2]; //data source array
        DataSource outputDataSource = null; // file to output

        DataSink outputDataSink = null; // datasink for output file

        MediaLocator videoLocator = new MediaLocator(oml.getURL()); //media locator for video 
        MediaLocator audioLocator = new MediaLocator(realAudioFile.toURI().toURL()); //media locator for audio

        FileTypeDescriptor outputType = new FileTypeDescriptor(FileTypeDescriptor.QUICKTIME); //output video format type

        Format outputFormat[] = new Format[2]; //format array 
        VideoFormat videoFormat = new VideoFormat(VideoFormat.JPEG); // output video codec MPEG does not work on windows
        javax.media.format.AudioFormat audioMediaFormat = new javax.media.format.AudioFormat(
                javax.media.format.AudioFormat.LINEAR, 44100, 16, 1); //audio format


        outputFormat[0] = videoFormat;
        outputFormat[1] = audioMediaFormat;

        //create processors for each file
        Processor videoProcessor = Manager.createProcessor(videoDataSource); 
        Processor audioProcessor = Manager.createProcessor(audioDataSource);
        Processor processor = null;

        //start video and audio processors
        videoProcessor.realize();
        audioProcessor.realize();
        //wait till they are realized
        while(videoProcessor.getState() != 300 && audioProcessor.getState() != 300) {
            Thread.sleep(100);
        }
        //get processors dataoutputs to merge
        arrayDataSource[0] = videoProcessor.getDataOutput();
        arrayDataSource[1] = audioProcessor.getDataOutput();

        videoProcessor.start();
        audioProcessor.start();

        //create merging data source
        mixedDataSource = javax.media.Manager.createMergingDataSource(arrayDataSource);
        mixedDataSource.connect();
        mixedDataSource.start();
        //init final processor to create merged file
        ProcessorModel processorModel = new ProcessorModel(mixedDataSource, outputFormat, outputType);
        processor = Manager.createRealizedProcessor(processorModel);
        processor.addControllerListener(this);
        processor.configure();
        //wait till configured
        while(processor.getState() < 180) {
            Thread.sleep(20);
        }

        processor.setContentDescriptor(new ContentDescriptor(FileTypeDescriptor.QUICKTIME));

        TrackControl tcs[] = processor.getTrackControls();
        Format f[] = tcs[0].getSupportedFormats();

        tcs[0].setFormat(f[0]);

        processor.realize();
        //wait till realized
        while(processor.getState() < 300) {
            Thread.sleep(20);
        }
        //create merged file and start writing media to it
        outputDataSource = processor.getDataOutput();
        MediaLocator outputLocator = new MediaLocator("file:/"+directory.getAbsolutePath()+"/yourmovfile.mov");
        outputDataSink = Manager.createDataSink(outputDataSource, outputLocator);
        outputDataSink.open();
        outputDataSink.addDataSinkListener(this);
        outputDataSink.start();
        processor.start();

        while(processor.getState() < 500) {
            Thread.sleep(100);
        }
        //wait until writing is done
        waitForFileDone();
        //dispose processor and datasink
        outputDataSink.stop();
        processor.stop();

        outputDataSink.close();
        processor.close();

    } catch (NoDataSourceException | IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IncompatibleSourceException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoDataSinkException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoProcessorException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (CannotRealizeException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

Object waitFileSync = new Object();
boolean fileDone = false;
boolean fileSuccess = true;
Object waitSync = new Object();
boolean stateTransitionOK = true;

/**
 * Block until file writing is done.
 */
boolean waitForFileDone() {
    synchronized (waitFileSync) {
        try {
            while (!fileDone)
                waitFileSync.wait();
        } catch (Exception e) {
        }
    }
    return fileSuccess;
}

/**
 * Event handler for the file writer.
 */
public void dataSinkUpdate(DataSinkEvent evt) {

    if (evt instanceof EndOfStreamEvent) {
        synchronized (waitFileSync) {
            fileDone = true;
            waitFileSync.notifyAll();
        }
    } else if (evt instanceof DataSinkErrorEvent) {
        synchronized (waitFileSync) {
            fileDone = true;
            fileSuccess = false;
            waitFileSync.notifyAll();
        }
    }
}

@Override
public void controllerUpdate(ControllerEvent evt) {
    if (evt instanceof ConfigureCompleteEvent
            || evt instanceof RealizeCompleteEvent
            || evt instanceof PrefetchCompleteEvent) {
        synchronized (waitSync) {
            stateTransitionOK = true;
            waitSync.notifyAll();
        }
    } else if (evt instanceof ResourceUnavailableEvent) {
        synchronized (waitSync) {
            stateTransitionOK = false;
            waitSync.notifyAll();
        }
    } else if (evt instanceof EndOfMediaEvent) {
        evt.getSourceController().stop();
        evt.getSourceController().close();
    }

}

你的类必须实现ControllerListener、DataSinkListener。视频和音频同步非常适合我(音频有半秒的变化,但对我来说不是问题)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将音频与视频结合(不使用 ffmpeg)- Java 的相关文章

随机推荐

  • 有人有使用 scipy.stats.distributions 的示例代码吗?

    我正在努力弄清楚如何使用 scipy distributions 包 并想知道是否有人可以为我发布一些示例代码 它似乎可以满足我需要的一切 我只是不知道如何使用它 我需要生成两种分布 一种是对数正态分布 一种是泊松分布 我知道每个的方差和
  • Ruby String.encode 仍然给出“UTF-8 中的无效字节序列”

    在 IRB 中 我正在尝试以下操作 1 9 3p194 001 gt foo xBF encode utf 8 invalid gt replace undef gt replace gt xBF 1 9 3p194 002 gt foo
  • NodeJS JSON.stringify 非常长的对象数组错误“字符串长度无效”

    我有一个很长的对象数组 大小约为 100 000 个项目 就在将其写入文件之前 我将数据传递到 JSON stringify 我收到此错误 JSON stringify RangeError Invalid string length 如何
  • 如何在视图文件夹中包含 js.erb 文件

    我有一个与视图一起使用的 JavaScript 文件 里面需要有 Ruby 代码 我需要做render在 Ruby 中 所以我知道我不能将 JavaScript 文件放入资产管道中 我可以将它放在与 html erb file 如何包含 J
  • 蓝牙 LE 外围设备在与蓝牙 LE 中央设备连接时停止广告

    我想开发像蓝牙 LE 外围设备这样的应用程序 它会在与蓝牙 LE 中央设备连接时停止广告 并限制与多个蓝牙 LE 中央设备连接的蓝牙 LE 外围设备 一台蓝牙 LE 外围设备一次仅与一台蓝牙 LE 中心连接 成功连接蓝牙 LE 外围设备和蓝
  • Rhino Mocks 上的模拟和存根有什么区别?

    我对此还没有玩够 通常使用模拟 但我想知道这两者之间有什么区别 以及何时在 Rhino Mocks 上使用其中之一 Update 我还在中找到了我的问题的答案阿延德的话 存根和模拟之间的区别您可以在本文中获得这些术语的实际定义 模拟不是存根
  • 如何使用给定模式 tail -f 最新日志文件

    我使用一些日志系统 它每小时创建一个日志文件 如下所示 SoftwareLog 2010 08 01 08 SoftwareLog 2010 08 01 09 SoftwareLog 2010 08 01 10 我试图跟踪最新的日志文件给出
  • Google Keep 如何在保存录音的同时进行语音识别?

    Android 的 SpeechRecognizer 显然不允许将您正在进行语音识别的输入记录到音频文件中 也就是说 要么使用 MediaRecorder 或 AudioRecord 录制语音 要么使用 SpeechRecognizer 进
  • JavaScript 中所有可打印字符的正则表达式

    寻找验证所有可打印字符的正则表达式 正则表达式仅需要在 JavaScript 中使用 我已经经历过this帖子 但主要讨论 net Java 和 C 但不讨论 JavaScript 您必须只允许这些可打印字符 a z A Z 0 9 以及三
  • 导入错误:无法在新安装上导入名称“opentype”

    我刚刚创建了一个 Google Cloud 计算引擎 安装了带有 pip 和 pip3 的 google cloud 软件包 并且在使用 python3 启动脚本时遇到以下错误 from google cloud import bigque
  • 无法加载程序集,HRESULT 异常:0x80131040

    例外 无法加载文件或程序集 WPFVisifire Charts Version 4 1 0 0 Culture neutral PublicKeyToken 99d724542e4db593 或其依赖项之一 找到的程序集的清单定义与程序集
  • 正则表达式:如何只允许大于零的整数

    我尝试了以下方法 只允许在文本框中输入整数 这很好用 但它允许其中有零 我还可以添加其他内容来防止添加零吗 d 这将允许 10 但不允许 01 并且只允许由数字组成的数字 即没有句点或减号 但也没有加号 科学记数法等 1 9 0 9
  • 如何强制 MVC 验证 IValidatableObject

    看起来 当 MVC 验证模型时 它首先运行 DataAnnotation 属性 如必需的或范围 如果其中任何一个失败 它会跳过在我的 IValidatableObject 模型上运行 Validate 方法 即使其他验证失败 是否有办法让
  • 在 SwiftUI 中将视图动画化以向上滑动并点击隐藏

    我创建了一个横幅修改器 从顶部显示横幅 这动画效果很好 但是 当我点击以关闭它时 它根本没有动画 只是隐藏 即使点击手势动作已withAnimation包裹它 struct BannerModifier ViewModifier Bindi
  • 无法从 QQmlPropertyMap 子类中的 QML 调用槽或 Q_INVOKABLE

    我正在尝试试驾QQmlPropertyMap班级 如果我可以对它进行子类化 它似乎可以很好地满足我的需求 文档here甚至给出了一些关于如何对其进行子类化的基本说明 所述文档还表明该类派生自QObject 就其价值而言 我在 Qt 5 0
  • 动态添加新元素后,jQuery 选择器不会更新

    我的选择器是 section attendance input last 但是 我将另一个输入附加到section attendance 我希望选择器现在选择该元素 因为它应该如此 因为 last 然而 由于某种原因 它没有 我不太确定为什
  • C++函数有默认返回值吗? [复制]

    这个问题在这里已经有答案了 我很惊讶包含以下代码行的文件已成功编译并且链接器生成可执行文件 我认为所有功能 除了main 必须有一个有效的return语句 除非返回类型是void int foo double bar int main 我缺
  • 从 CMD 返回错误代码到 Powershell

    我正在编写 Mssql 安装脚本 我想获得静默 mssql 安装的结果 在我的 PowerShell 脚本中 我运行以下命令 result start cmd c D SQL2008R2 SQL2008R2 setup exe CONFIG
  • 将 blob 文件发送到服务器

    我正在尝试将录音发送到服务器并将其另存为 wav 我在前端使用 Angular 在服务器上使用 net core 我能够录制 然后制作一个 音频 wav 类型的斑点 为了将其发送到服务器 我将其转换为数组缓冲区 然后将数组缓冲区转换为 Ba
  • 将音频与视频结合(不使用 ffmpeg)- Java

    我正在构建一个小程序来捕获屏幕和麦克风输入 音频 我可以单独录制这些文件 但找不到将这些文件组合起来制作新的音频视频的方法 视频文件位于 mov格式和音频是 wav格式 它们的长度完全相同 有什么办法可以合并这些文件吗 我尝试过 Java