代码之家  ›  专栏  ›  技术社区  ›  GOXR3PLUS

字节数为负数的Java AudioInputStream skip始终返回0

  •  0
  • GOXR3PLUS  · 技术社区  · 7 年前

    我试图跳过负字节数 AudioInputStream skip(long bytes) 方法。

    问题是试图(比如说少量字节…):

    int skipped = audioInputStream.skip(-bytes);
    

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


    Here is the full code 在github上的图书馆。

    我做的是每次用户跳过音频时重新创建线路

    /**                                                                                                                   
     * 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;                                                                                              
    }                                                                                                                     
    

    继续这个问题。。。 Java AudioInputStream how to support skip with negative number of bytes

    1 回复  |  直到 7 年前
        1
  •  2
  •   Slaw    7 年前

    AudioInputStream.skip 不支持否定参数。如果你读了 InputStream.skip 上面写着( 强调

    跳过并丢弃此输入流中的n字节数据。这个 skip 由于各种原因,方法可能会跳过一些较小的字节数,可能 0 . 这可能是由许多情况中的任何一种造成的;在跳过n个字节之前到达文件结尾只是一种可能。返回跳过的实际字节数。 如果 n 是否定的 跳过 类的方法 InputStream 总是返回 ,并且不跳过任何字节。 子类可能以不同的方式处理负值。

    它确实提到子类可以改变这种行为,但是 AudioInputStream 没有任何迹象表明它会这样做。

    阶级( )javadoc公司:

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

    这个 AudioSystem 音频输入流

    • 从外部音频文件、流或 URL
    • 从音频输入流写入外部文件

    音频输入流.skip javadoc公司:

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

    这种方法总是跳过整数帧。如果 n个 不指定整数帧数,最大值为 n - (n % frameSize)

    另外,如果您查看 音频输入流.skip if 语句立即返回 0个 n个 <= 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源代码。

    推荐文章