【问题标题】:Code runs when in a main method but not when in another method代码在 main 方法中运行,但在另一个方法中不运行
【发布时间】:2019-01-15 04:44:49
【问题描述】:

我创建了 setArtwork 方法来在 .m4a 容器中设置 aac 文件的图稿,当我运行 main 方法时,它完全符合我的要求

public static void setArtwork(File art, File m4a) throws Exception{
    Mp4TagReader reader = new Mp4TagReader();
    Mp4TagWriter writer = new Mp4TagWriter();
    RandomAccessFile song = new RandomAccessFile(m4a.toString(),"rw");
    Mp4Tag mp4tag = reader.read(song);

    Artwork artwork = ArtworkFactory.createArtworkFromFile(art);
    mp4tag.addField(artwork);
    mp4tag.setField(artwork);

    RandomAccessFile temp = new RandomAccessFile(m4a,"rw");
    writer.write(mp4tag,song,temp);
}
public static void main(String[] args) throws Exception{
    File art = new File("C:\\Users\\Zubair\\Documents\\music\\coverArt.jpeg");
    File m4a = new File("C:\\Users\\Zubair\\Documents\\music\\song.m4a");
    setArtwork(art,m4a);
}

但是,当我尝试在不同类的不同方法中使用 setArtwork 方法时,它实际上并没有将 mp4 标记保存到文件中。我做了一些调试,看看图片是否被添加到艺术品标签中,一切看起来都不错,但似乎标签没有被写入文件。

public static void mp3Tom4a(File mp3File, File m4aFolder, File coverArt) throws Exception {
    String input = mp3File.toString();
    String name = mp3File.getName();

    String output = name.substring(0,name.indexOf(MP3)) + M4A;
    output = m4aFolder.toString() + "\\" + output;

    //cd ffmpeg\bin && ffmpeg -y -i input.mp3 -an -vcodec copy cover.jpg && ffmpeg -y -i input.mp3 -c:a aac -b:a 192k -vn output.m4a
    ProcessBuilder builder = new ProcessBuilder(
            "cmd.exe","/c","cd ffmpeg\\bin && ffmpeg -y -i "
            + input +" -an -vcodec copy "+coverArt+
            " && ffmpeg -y -i " + input + " -c:a aac -b:a 128k -vn " + output);
    builder.redirectErrorStream(true);
    builder.start();
    JAudioData.setArtwork(coverArt,new File(output));
}
public static void main(String[] args) throws Exception {
    mp3Tom4a(new File("C:\\Users\\Zubair\\Documents\\music\\song.mp3"),
            new File("C:\\Users\\Zubair\\Documents\\music"),
            new File("C:\\Users\\Zubair\\Documents\\music\\coverArt.jpeg"));
}

setArtwork 只在它自己类的main方法中才起作用是没有意义的,特别是因为我用于参数的对象彼此相同,所以结果应该没有区别。我认为这可能与正在更新的 RandomAccessFile 对象有关,但物理存储没有得到更新

编辑-如果我注释掉 builder.start() 那么它可以成功地将 mp4tag 写入 m4a 文件。但我不明白为什么拥有 builder.start() 会阻止这种情况发生。我最好的猜测是,因为 builder.start() 是创建 song.m4a 的原因,所以它仍然被“编辑”,不能被任何其他进程编辑。

【问题讨论】:

  • 我猜你是假设外部进程已经成功完成了你可以setArtwork的时间?
  • @ScaryWombat 我已经进行了一些调试以查看 setArtwork 方法是否可以运行。它最终会运行并创建一个添加了正确图稿的 mp4tag,但我没有看到将新标签写入原始文件。但是当我从第一类运行 main 方法时不会出现这个错误
  • 是否抛出异常?
  • @ScaryWombat 不会抛出异常。它的执行与在 main 方法中执行的一样,但是当我检查 song.m4a 的属性时,什么都没有改变。
  • 如果您省略首先调用外部进程,也许可以尝试检查它是否有效

标签: java ffmpeg processbuilder randomaccessfile


【解决方案1】:

我从另一个帖子中找到了答案

https://stackoverflow.com/a/5483976/10194055

上课过程

由于部分原生平台只为标准输入输出流提供有限的缓冲区大小,未能及时写入子进程的输入流或读取输出流可能会导致子进程阻塞,甚至死锁。

无法从 Process 清除输入流的缓冲区(通过管道连接到 >subprocess 的输出流)可能导致子进程阻塞。

这是我的功能代码的样子。其他类和方法保持不变

public static void mp3Tom4a(File mp3File, File m4aFolder, File coverArt) throws Exception {

    String input = mp3File.toString();
    String name = mp3File.getName();

    String output = name.substring(0, name.indexOf(MP3)) + M4A;
    output = m4aFolder.toString() + "\\" + output;
    //cd ffmpeg\bin && ffmpeg -y -i input.mp3 -an -vcodec copy cover.jpg && ffmpeg -y -i input.mp3 -c:a aac -b:a 192k -vn output.m4a
    ProcessBuilder builder = new ProcessBuilder(
            "cmd.exe", "/c", "cd ffmpeg\\bin && ffmpeg -y -i "
            + input + " -an -vcodec copy " + coverArt +
            " && ffmpeg -y -i " + input + " -c:a aac -b:a 128k -vn " + output);
    builder.redirectErrorStream(true);
    Process p = builder.start();
    BufferedReader reader =
            new BufferedReader(new InputStreamReader(p.getInputStream()));
    while ((reader.readLine()) != null) {}
    p.waitFor();

    JAudioData.setArtwork(coverArt, new File(output));
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-10
    相关资源
    最近更新 更多