负字节数的Java AudioInputStream跳过总是返回0 [英] Java AudioInputStream skip with negative number of bytes always returns 0

查看:109
本文介绍了负字节数的Java AudioInputStream跳过总是返回0的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用AudioInputStream跳过负数个字节 skip(long bytes)方法.

I am trying to skip a negative number of bytes with AudioInputStream skip(long bytes) method .

问题正在尝试(假设有少量字节...):

The problem is trying to (let's say a small number of bytes...) :

int skipped = audioInputStream.skip(-bytes);

总是返回0....我不知道该怎么办.

这是github上库的完整代码 .

我要做的是每当用户跳过音频时重新创建线路 当我当然可以做得更好的时候,这会非常慢... ...只是向前或向后前进.现在它仅支持转发...

What i do is recreating the line every time the user skips audio which is extremely slow when i can of course do much better ... by just going backward or forward . Now it supports only forward ...

/**                                                                                                                   
 * Skip bytes in the File input stream. It will skip N frames matching to bytes, so it will never skip given bytes len
 *                                                                                                                    
 * @param bytes                                                                                                       
 *            the bytes                                                                                               
 * @return value bigger than 0 for File and value = 0 for URL and InputStream                                         
 * @throws StreamPlayerException                                                                                      
 *             the stream player exception                                                                            
 */                                                                                                                   
public long seek(long bytes) throws StreamPlayerException {                                                           
    long totalSkipped = 0;                                                                                            

    //If it is File                                                                                                   
    if (dataSource instanceof File) {                                                                                 

        //Check if the requested bytes are more than totalBytes of Audio                                              
        long bytesLength = getTotalBytes();                                                                           
        System.out.println("Bytes: " + bytes + " BytesLength: " + bytesLength);                                       
        if ( ( bytesLength <= 0 ) || ( bytes >= bytesLength )) {                                                      
            generateEvent(Status.EOM, getEncodedStreamPosition(), null);                                              
            return totalSkipped;                                                                                      
        }                                                                                                             

        logger.info(() -> "Bytes to skip : " + bytes);                                                                
        Status previousStatus = status;                                                                               
        status = Status.SEEKING;                                                                                      

        try {                                                                                                         
            synchronized (audioLock) {                                                                                
                generateEvent(Status.SEEKING, AudioSystem.NOT_SPECIFIED, null);                                       
                initAudioInputStream();                                                                               
                if (audioInputStream != null) {                                                                       

                    long skipped;                                                                                     
                    // Loop until bytes are really skipped.                                                           
                    while (totalSkipped < ( bytes )) { //totalSkipped < (bytes-SKIP_INACCURACY_SIZE)))                
                        //System.out.println("Running");                                                              
                        skipped = audioInputStream.skip(bytes - totalSkipped);                                        
                        if (skipped == 0)                                                                             
                            break;                                                                                    
                        totalSkipped += skipped;                                                                      
                        logger.info("Skipped : " + totalSkipped + "/" + bytes);                                       
                        if (totalSkipped == -1)                                                                       
                            throw new StreamPlayerException(StreamPlayerException.PlayerException.SKIP_NOT_SUPPORTED);

                        logger.info("Skeeping:" + totalSkipped);                                                      
                    }                                                                                                 
                }                                                                                                     
            }                                                                                                         
            generateEvent(Status.SEEKED, getEncodedStreamPosition(), null);                                           
            status = Status.OPENED;                                                                                   
            if (previousStatus == Status.PLAYING)                                                                     
                play();                                                                                               
            else if (previousStatus == Status.PAUSED) {                                                               
                play();                                                                                               
                pause();                                                                                              
            }                                                                                                         

        } catch (IOException ex) {                                                                                    
            logger.log(Level.WARNING, ex.getMessage(), ex);                                                           
        }                                                                                                             
    }                                                                                                                 
    return totalSkipped;                                                                                              
}                                                                                                                     


此问题的继续在这里... 推荐答案

AudioInputStream.skip不支持否定参数.如果您阅读InputStream.skip的Javadoc,则说(强调我的):

AudioInputStream.skip does not support negative arguments. If you read the Javadoc of InputStream.skip it says (emphasis mine):

跳过并丢弃此输入流中的n个字节的数据.出于各种原因,skip方法可能最终跳过了一些较小的字节,可能是0.这可能是由多种条件引起的;在跳过n个字节之前到达文件末尾只是一种可能.返回跳过的实际字节数. 如果n为负,则类InputStreamskip方法始终返回0,并且不会跳过任何字节.子类可能会以不同的方式处理负值.

Skips over and discards n bytes of data from this input stream. The skip method may, for a variety of reasons, end up skipping over some smaller number of bytes, possibly 0. This may result from any of a number of conditions; reaching end of file before n bytes have been skipped is only one possibility. The actual number of bytes skipped is returned. If n is negative, the skip method for class InputStream always returns 0, and no bytes are skipped. Subclasses may handle the negative value differently.

它确实提到了子类可能会改变这种行为,但是AudioInputStream的文档并未给出任何指示.

It does mention that subclasses may change this behavior but the documentation of AudioInputStream does not give any indication it does this.

类(AudioInputStream)javadoc:

Class (AudioInputStream) javadoc:

音频输入流是具有指定音频格式和长度的输入流.长度以样本帧而不是字节表示.提供了几种方法来从流中读取一定数量的字节或未指定数量的字节.音频输入流会跟踪读取的最后一个字节.您可以跳过任意数量的字节以到达以后的位置进行读取.音频输入流可以支持标记.设置标记时,会记住当前位置,以便稍后返回.

An audio input stream is an input stream with a specified audio format and length. The length is expressed in sample frames, not bytes. Several methods are provided for reading a certain number of bytes from the stream, or an unspecified number of bytes. The audio input stream keeps track of the last byte that was read. You can skip over an arbitrary number of bytes to get to a later position for reading. An audio input stream may support marks. When you set a mark, the current position is remembered so that you can return to it later.

AudioSystem类包括许多操作AudioInputStream对象的方法.例如,这些方法可让您:

The AudioSystem class includes many methods that manipulate AudioInputStream objects. For example, the methods let you:

  • 从外部音频文件,流或URL
  • 获取音频输入流
  • 从音频输入流中写入外部文件
  • 将音频输入流转换为其他音频格式
  • obtain an audio input stream from an external audio file, stream, or URL
  • write an external file from an audio input stream
  • convert an audio input stream to a different audio format

AudioInputStream.skip javadoc:

跳过并丢弃此音频输入流中指定数量的字节.

Skips over and discards a specified number of bytes from this audio input stream.

此方法将始终跳过整数帧.如果n未指定整数帧,则将最多跳过n - (n % frameSize)个字节.

This method will always skip an integral number of frames. If n does not specify an integral number of frames, a maximum of n - (n % frameSize) bytes will be skipped.

此外,如果查看AudioInputStream.skip的实现,则可以看到如果n<= 0,第二个if语句立即返回0.

Also, if you look at the implementation of AudioInputStream.skip you can see that the second if statement immediately returns 0 if n is <= 0.

@Override
public long skip(long n) throws IOException {
    // make sure not to skip fractional frames
    final long reminder = n % frameSize;
    if (reminder != 0) {
        n -= reminder;
    }
    if (n <= 0) {
        return 0;
    }

    if (frameLength != AudioSystem.NOT_SPECIFIED) {
        // don't skip more than our set length in frames.
        if ((n / frameSize) > (frameLength - framePos)) {
            n = (frameLength - framePos) * frameSize;
        }
    }
    long remaining = n;
    while (remaining > 0) {
        // Some input streams like FileInputStream can return more bytes,
        // when EOF is reached.
        long ret = Math.min(stream.skip(remaining), remaining);
        if (ret == 0) {
            // EOF or not? we need to check.
            if (stream.read() == -1) {
                break;
            }
            ret = 1;
        } else if (ret < 0) {
            // the skip should not return negative value, but check it also
            break;
        }
        remaining -= ret;
    }
    final long temp =  n - remaining;

    // if no error, update our position.
    if (temp % frameSize != 0) {
        // Throw an IOException if we've skipped a fractional number of frames
        throw new IOException("Could not skip an integer number of frames.");
    }
    framePos += temp/frameSize;
    return temp;
}

Java 10源代码.

这篇关于负字节数的Java AudioInputStream跳过总是返回0的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆