当前位置: 首页 > 知识库问答 >
问题:

TargetDataLine和Xuggler通过屏幕视频录制音频

司马英才
2023-03-14

TargetDataLine是迄今为止用Java捕获麦克风输入的最简单方法。我想对我用屏幕视频(在屏幕录制软件中)捕获的音频进行编码,以便用户可以创建教程、幻灯片盒等。
我使用Xuggler对视频进行编码<他们确实有一个用视频编码音频的教程,但他们从文件中获取音频。就我而言,音频是实时的

参考文献:
1. DavaDoc for TargetDataLine:http://docs.oracle.com/javase/1.4.2/docs/api/javax/sound/sampled/TargetDataLine.html
2. Xugler文档:http://build.xuggle.com/view/Stable/job/xuggler_jdk5_stable/javadoc/java/api/index.html

public void run(){
        final IRational FRAME_RATE = IRational.make(frameRate, 1);
        final IMediaWriter writer = ToolFactory.makeWriter(completeFileName);
        writer.addVideoStream(0, 0,FRAME_RATE, recordingArea.width, recordingArea.height);
        long startTime = System.nanoTime();

        while(keepCapturing==true){
            image = bot.createScreenCapture(recordingArea);
            PointerInfo pointerInfo = MouseInfo.getPointerInfo();
            Point globalPosition = pointerInfo.getLocation();

            int relativeX = globalPosition.x - recordingArea.x;
            int relativeY = globalPosition.y - recordingArea.y;

            BufferedImage bgr = convertToType(image,BufferedImage.TYPE_3BYTE_BGR);
            if(cursor!=null){
                bgr.getGraphics().drawImage(((ImageIcon)cursor).getImage(), relativeX,relativeY,null);
            }
            try{
                writer.encodeVideo(0,bgr,System.nanoTime()-startTime,TimeUnit.NANOSECONDS);
            }catch(Exception e){
                writer.close();
                JOptionPane.showMessageDialog(null, 
                        "Recording will stop abruptly because" +
                        "an error has occured", "Error",JOptionPane.ERROR_MESSAGE,null); 
            }

            try{
                sleep(sleepTime);
            }catch(InterruptedException e){
                e.printStackTrace();
            }
        }
        writer.close();

    }

共有1个答案

卞浩漫
2023-03-14

我最近在这个问题下回答了大部分问题:Xugler编码和混搭

代码示例

writer.addVideoStream(videoStreamIndex, 0, videoCodec, width, height);
writer.addAudioStream(audioStreamIndex, 0, audioCodec, channelCount, sampleRate);

while (... have more data ...)
{
    BufferedImage videoFrame = ...;
    long videoFrameTime = ...; // this is the time to display this frame
    writer.encodeVideo(videoStreamIndex, videoFrame, videoFrameTime, DEFAULT_TIME_UNIT);

    short[] audioSamples = ...; // the size of this array should be number of samples * channelCount
    long audioSamplesTime = ...; // this is the time to play back this bit of audio
    writer.encodeAudio(audioStreamIndex, audioSamples, audioSamplesTime, DEFAULT_TIME_UNIT);
}

对于TargetDataLine,getMicrosecondPosition()将告诉您audioSamplesTime所需的时间。这似乎是从打开TargetDataLine时开始的。您需要弄清楚如何获取引用同一时钟的视频时间戳,这取决于视频设备和/或捕获视频的方式。只要它们都使用相同的时钟,绝对值就无关紧要。您可以从视频和音频时间中减去初始值(在流开始时),以便时间戳匹配,但这只是一个近似匹配(在实践中可能足够接近)。

您需要以严格递增的时间顺序调用codeVideocodeAudio;您可能必须缓冲一些音频和一些视频以确保您可以做到这一点。这里有更多详细信息。

 类似资料:
  • 问题内容: 我想使用Xuggler 将无音频的视频文件与音频文件合并。此刻,我已经采取了两个流,并将这些流的视频和音频部分分别合并为画中画。现在,我想将音频和视频文件相互组合。任何建议或提示将不胜感激。我正在使用red5服务器。谢谢。 问题答案: 使用MediaConcatenator。请参见示例代码“连接音频和视频”

  • 我能够在MediaCodec和MediaMuxer的帮助下录制(编码)视频。接下来,我需要在MediaCodec和MediaMuxer的帮助下处理音频部分和带视频的mux音频。 我面临两个问题: > 如何将音频和视频数据传递给MediaMuxer(因为writeSampleData()方法一次只接受一种类型的数据)? 我提到了MediaMuxerTest,但它使用的是MediaExtractor。

  • 我做了这个webapp来作曲,我想添加一个功能来下载作曲作为.mp3/wav/whateverfileformatprobabile,我一直在搜索如何这样做很多次,但总是放弃,因为我找不到任何例子如何做,只有东西我找到了麦克风录音机,但我想记录最终的音频目的地的网站。我是这样播放音频的: 其中buf是audiobuffer。 综上所述,我想录下整个窗口音频却想不出办法。

  • 我是gstreamer的新手,我想录制音频和视频并将其保存到。mp4格式,使用网络摄像头录制视频,使用麦克风录制音频这是我的管道 gst-launch-1.0-e v4l2src!队列x264enc!H264解析!队列qtmux0.alsasrc!'音频/x-raw,速率=44100,深度=24’!音频转换!音频重采样!voaacenc!aacparse!qtmux!filesink locati