2011-09-14 21 views
14

Chúng tôi đang sử dụng MediaRecorder để quay video vào tệp trên bộ nhớ ngoài bằng cách sử dụng setOutputFile() trước khi thực hiện ghi âm thực tế.Cách biết khi nào MediaRecorder đã hoàn tất ghi dữ liệu vào tệp

Mọi thứ hoạt động tốt, nhưng vấn đề chính là ngay sau khi quá trình ghi được thực hiện, chúng tôi muốn bắt đầu phát lại video đã quay lại trong VideoView.

Làm thế nào để biết khi nào tệp đã sẵn sàng để đọc và phát lại?

Trả lời

18

Lớp học FileObserver phù hợp với nhu cầu của bạn một cách hoàn hảo. Here is the documentation. Dễ sử dụng. Khi một tập tin quan sát được đóng lại sau khi viết, cuộc gọi lại onEvent được gọi với tham số CLOSE_WRITE.

MyFileObserver fb = new MyFileObserver(mediaFile_path, FileObserver.CLOSE_WRITE); 
fb.startWatching(); 

class MyFileObserver extends FileObserver { 

    public MyFileObserver (String path, int mask) { 
     super(path, mask); 
    } 

    public void onEvent(int event, String path) { 
     // start playing 
    } 
} 

Dont quên gọi stopWatching() ..

+0

Tôi không thể kiểm tra điều này ngay bây giờ, nhưng bạn có biết nếu nó được đảm bảo rằng MediaRecorder không đóng tệp giữa các lần ghi? –

+0

Không nhận thức được điều đó. Nhưng ngay cả khi có, bạn có thể duy trì trạng thái ghi trong một thành viên và kiểm tra nó trong 'onEvent'. Nếu quá trình ghi bị tạm dừng, chỉ cần bỏ qua sự kiện. – Ronnie

+0

Đúng. Tôi nghĩ rằng đây có vẻ là giải pháp tốt nhất, cảm ơn bạn! –

0

Dường như không có cách nào để phát hiện khi bản ghi đã dừng trong Trình phát đa phương tiện, nhưng có một điểm dừng() mà bạn có thể ghi đè nếu bạn tạo một lớp tùy chỉnh triển khai MediaRecorder. ở đây tôi sẽ làm một cái gì đó như thế này:

public class MyRecorder implements MediaRecorder { 
    public boolean stopped; 

    .... implement all the methods that MediaRecorder has making 
     sure to call super for each method. 

    @Override 
    public void myStop() { 
     this.stopped = true; 
     super.stop(); 
    } 
} 

Sau đó, bạn có thể truy cập vào boolean để xem liệu nó có dừng ghi âm hay không.

+1

Nhưng khi dừng ghi, nhiều dữ liệu hơn phải được ghi vào bộ nhớ và chúng tôi không thể bắt đầu phát video cho đến khi bản ghi thực sự được ghi vào bộ nhớ. –

+0

Điều gì phải được viết? Nếu tùy chỉnh những gì bạn đang viết thì hãy gọi hàm tùy chỉnh của bạn từ bên trong phương thức dừng ghi đè rồi đặt biến đã dừng sau cuộc gọi của bạn. – JPM

+2

Tôi biết khi nào chúng tôi _stop_ ghi âm. Khi ghi âm bị dừng lại, máy ghi ghi dữ liệu vào đĩa và tôi muốn biết khi nào nó đã hoàn thành dữ liệu ghi :) –

0

Cách bẩn sẽ là kiểm tra giá trị lastModified() của Tệp và mở VideoView nếu Tệp không được sửa đổi trong 2 giây.

+0

Chúng tôi đã có sẵn hacks, nhưng tôi thích một giải pháp thích hợp hơn nếu có. Nếu không có, tốt, sau đó chúng tôi sẽ chỉ tiếp tục sử dụng hack của chúng tôi và thêm một số lỗi bảo vệ cho nó :) –

5

Chúng tôi giải quyết vấn đề tương tự với algo sau:

while (file not complete) 
    sleep for 1 sec 
    read the fourth byte of the file 
    if it is not 0 (contains 'f' of the 'ftyp' header) then 
     file is complete, break 

Điểm mấu chốt là MediaRecorder viết hộp ftyp tại thời điểm cuối cùng. Nếu nó được đặt đúng vị trí, thì tệp hoàn tất.

+0

Điều này là đầy hứa hẹn! Sẽ có một đi lúc này, cảm ơn. –

1

Tôi đã không cố gắng này bản thân mình nhưng điều này có thể làm việc:

public void phát hành() Kể từ: API Level 1

chí nguồn lực liên quan đến đối tượng MediaRecorder này. Đó là thực tiễn tốt để gọi phương thức này khi bạn hoàn tất sử dụng MediaRecorder.

Nếu thực hiện điều này, thì tôi đoán nếu bạn gọi phương thức này và sau khi phương thức này trả về, bạn biết tệp đã sẵn sàng.

+0

Thật sao? Tôi nghĩ rằng đó chỉ là để phát hành tài nguyên và cho phép thỏa thuận GC với họ, ngoài ra, chúng tôi ghi lại nhiều clip để tái tạo MediaRecorder mỗi lần có thể sẽ làm tổn thương hiệu suất cho chúng tôi. Tôi sẽ điều tra nó hơn nữa mặc dù, cảm ơn! –

1

Trong các thử nghiệm của tôi không phụ thuộc vào kích thước của mediaRecorder.stop ghi() là một phương pháp ngăn chặn mà chỉ trả lại sau khi tập tin đã được hoàn toàn bằng văn bản và đóng cửa bởi máy ghi âm.

Vì vậy, câu trả lời của JPM thực sự chính xác.

Bạn có thể xác minh điều này bằng cách gọi File.length() ngay sau khi dừng(). Bạn sẽ thấy rằng độ dài tệp đầu ra là độ dài cuối cùng của tệp tại thời điểm này. Nói cách khác, thiết bị ghi phương tiện không ghi thêm bất cứ thứ gì vào tệp sau khi dừng() đã trở lại.

0

Tôi đã gặp vấn đề tương tự trong xamarin và đã thử tất cả các giải pháp này (ngoại trừ giải pháp Ash).Điều cuối cùng tôi đã làm để giải quyết vấn đề là gọi hàm bên dưới trong hàm releaseMediaRecorder() trước khi Reset và trước khi Release được gọi.

mediaRecorder.setOutputFile("some new file") 
Các vấn đề liên quan