Java记录以缓冲并找到PCM_Unsigned音频中的间隙

时间:2018-07-10 05:38:49

标签: java audio audio-recording

我正在实现具有记录功能的网络广播播放器。基本记录有效,但是有一个功能,用户可以添加想要记录的标题,以便软件在某些工作站上监视这些标题。 每个电台的标题信息都是基于广播,不幸的是,它们被延迟了大约15-20秒,因此我必须缓冲录制并等待标题是否与用户之一匹配。 这是我到目前为止所做的:

public class MP3Recorder implements Recorder, Runnable {
    private boolean recording = false;
    private File recorderDirectory = WebradioPlayer.getSettings().getGeneralSettings().getRecordingDirectory();
    private MetainformationReader reader = null;

    @Override
    public void recordNow(URL url) throws LineUnavailableException, IOException {
        new Thread(new Runnable() {
            @Override
            public void run() {
                if (url == null) {
                    throw new IllegalArgumentException("URL was not valid");
                }
                File f = null;
                try {
                    HttpURLConnection con = (HttpURLConnection) url.openConnection();
                    InputStream in = con.getInputStream();
                    f = new File(recorderDirectory + "/" + generateFileName() + ".mp3");
                    Path path = Paths.get(f.toURI());
                    recording = true;
                    Logger.logInfo("started recording");
                    OutputStream out = new FileOutputStream(path.toFile());
                    byte[] buffer = new byte[4096];
                    int len;
                    while ((len = in.read(buffer)) > 0 && (recording)) {
                        out.write(buffer, 0, len);
                    }
                    out.close();

                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                Logger.logInfo("writing id3v1.1");
                ID3 id3 = new ID3v1Builder(createTitle().orElse("Webradio-Recording"), createArtist().orElse("Kein Interpret"))
                        .setYear(String.valueOf(Calendar.getInstance().get(Calendar.YEAR)).toString())
                        .setAlbum(WebradioPlayer.getPlayer().getIcyReader().getStationName())
                        .setGenre(1)
                        .build();
                id3.writeId3Info();
                id3.writeId3ToFile(f);
                Logger.logInfo("Wrote ID3: " + id3.toString());
                Logger.logInfo("finished writing id3 for file " + f.toString());
            }
        }).start();
    }

    private Optional<String> createTitle() {
        String s = WebradioPlayer.getPlayer().getIcyReader().getActualMusicTitle();
        String title = null;
        if (s.contains("/")) {
            title = s.split("/")[0];
        } else if (s.contains("-")) {
            title = s.split("-")[0];
        }
        return Optional.ofNullable(title);
    }

    private Optional<String> createArtist() {
        String s = WebradioPlayer.getPlayer().getIcyReader().getActualMusicTitle();
        String artist = null;
        if (s.contains("/")) {
            artist = s.split("/")[1];
        } else if (s.contains("-")) {
            artist = s.split("-")[1];
        }
        //replace possible spaces, tabs and line wraps after slash
        return Optional.ofNullable(artist);
    }

    private String generateFileName() {
        //remove everything but characters and numbers
        return FileUtilitie.generateFileNameForRecording();
    }

    @Override
    public void recordByTitle() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                recordToBuffer();
            }
        }).start();
    }

    private void recordToBuffer() {
        RingBuffer b = new RingBuffer();
        b.record();
        if(checkTitleMatch()) {
        b.finishTitleRecord();
        }
    }

    private boolean checkTitleMatch() {
    for(ScheduledRecord r: RecorderController.getScheduledRecords()) {
    if(reader.getActualMusicTitle().equalsIgnoreCase(r.toString()) {
    return true;
    }
    return false;
    }

    @Override
    public void stop() {
        this.recording = false;
    }

    @Override
    public void run() {

    }

    @Override
    public boolean isRecording() {
        return recording;
    }

    @Override
    public void setMetaInformationReader(MetainformationReader r) {
        this.reader = r;
    }
}

在我的环形缓冲区中,我正在记录到字节数组。如果标题匹配,如何找到缓冲记录中的空白? (我需要缩小“旧”标题的开头和新标题的开头的距离)

0 个答案:

没有答案