2012-07-27 37 views
6

Tôi đang phát tệp âm thanh bằng cách sử dụng BasicPlayer của jlGui (dựa trên Javasound). Tệp nằm trong phần Samba và tôi đang sử dụng Jcifs để truy cập. Nó cho tôi một số InputStream.Cách hiệu quả để tìm kiếm âm thanh trực tuyến qua mạng với InputStream

NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication(...); 

SmbFile f = new SmbFile(...); 
SmbFileInputStream audioIn = new SmbFileInputStream(f); 

int bufSize = 8096;//should I use f.length() here? 
audioBIS = new BufferedInputStream(audioIn, bufSize); 

audioBIS.mark(f.length()); 

    //call BasicPlayer 
play(audioBIS); 

tôi cần để có thể đặt con trỏ bất cứ nơi nào trong tập tin, giống như bất kỳ máy nghe nhạc thông thường. Giải pháp duy nhất tôi có thể nghĩ đến là sử dụng BufferedInputStream và kết hợp đánh dấu/đặt lại/bỏ qua mọi lúc tôi cần định vị lại con trỏ. Ngay sau khi tôi mở tệp và nhận Luồng, tôi gọi phương thức mark(), để reset() sau đó sẽ định vị lại tôi ngay từ đầu. Sau đó, với skip() tôi có thể đi đến nơi tôi muốn.

audioBIS.reset(); 
audioBIS.skip(newBytePosition); 

Vấn đề của tôi là cuộc gọi skip() chỉ hoạt động khi tôi chỉ định bộ đệm đủ lớn để chứa toàn bộ tệp.

Có cách nào hiệu quả hơn để thực hiện việc này không?

Trả lời

2

Tôi đã đi xuống cùng con đường giống như bạn hiện tại. Trường hợp này là chúng tôi đã có một máy chủ (và một phần SMB) chứa hàng ngàn tệp âm thanh. Các tệp này cần thiết để có thể phát trong ứng dụng.

Tôi bắt đầu với jCif và sửa đổi nguồn của BasicPlayer để xử lý SmbFile giống như cách đối phó với Tệp. Nó làm việc ổn, nhưng khi nói đến tìm kiếm/bỏ qua nó không thực sự thổi bạn đi. Miễn là bạn có kết nối tốt với máy chủ, bạn sẽ ổn thôi.

Tôi đã kết thúc việc bỏ giải pháp đó, và thay vào đó cài đặt tomcat6 trên máy chủ và triển khai một servlet nhỏ và đơn giản cho phép yêu cầu được thực hiện cho một tệp tại một vị trí nhất định. Máy khách sau đó sẽ nhận phản hồi như là một InputStream và chuyển nó vào BasicPlayer. Nó hoạt động tốt hơn nhiều và phát lại ngay lập tức. Mã này có nhiều hơn một chút so với những gì là hợp lý để dán ở đây, nhưng tôi sẵn sàng chia sẻ nó với bạn nếu bạn quan tâm.

+0

Giải pháp của bạn nghe rất thú vị, nhưng tôi không có đủ khả năng hiển thị ở phía máy chủ để cài đặt tomcat. Dù sao, tôi có thể nghĩ về một wrapper của BasicPlayer mà làm nhiều hơn hoặc ít hơn cùng một điều, chăm sóc tìm kiếm và chức năng getTime. Chỉ là một câu hỏi. Làm thế nào để bạn tạo ra một Inputstream dựa trên một offset đã cho? Câu trả lời được đưa ra [ở đây] (http://stackoverflow.com/questions/5923817/how-to-clone-an-inputstream) là cảm hứng và cũng ngụ ý bộ nhớ đệm, nhưng tôi lo lắng về chi phí mà tôi sẽ giới thiệu làm bản sao của mảng lớn. – Giuseppe

+0

Khi bạn nói InputStream dựa trên một offset đã cho, thì bạn có còn nói về jCifs (SmbFile) và offset theo byte không? – sbrattla

+0

Tôi đã đề cập đến phần mà bạn nói "Máy khách sau đó sẽ nhận phản hồi dưới dạng InputStream".Bạn không có nghĩa là máy chủ đáp ứng với một inputstream mà bắt đầu ở vị trí mong muốn? – Giuseppe

0

Thay thế. Bạn luôn có thể đóng luồng và tạo lại. Dường như đi nhanh và bạn quay lại vị trí 0 nếu cần.

Vì vậy, hãy theo dõi bạn đang ở đâu. Miễn là bạn di chuyển về phía trước, hãy giữ luồng và nhảy với skip(). Một khi bạn cần phải quay trở lại một lần nữa, đóng dòng đó và tạo một mới và bỏ qua() đến vị trí mong muốn.

Trừ khi ứng dụng nặng về backskipping tất cả các thời gian bạn nên ok.

Kết hợp điều đó trong luồng tùy chỉnh đẹp mới và bạn có luồng hỗ trợ đi qua lại.

Các vấn đề liên quan