के साथ कैमरे से एन्कोडिंग एच .264 मैं इसे एंड्रॉइड 4.1 (एक अपग्रेड किए गए असस ट्रांसफार्मर टैबलेट का उपयोग करके) पर काम करने की कोशिश कर रहा हूं। Alex's response to my previous question के लिए धन्यवाद, मैं पहले से ही कुछ कच्चे H.264 डेटा को फ़ाइल में लिखने में सक्षम था, लेकिन यह फ़ाइल केवल ffplay -f h264
के साथ बजाने योग्य है, और ऐसा लगता है कि यह फ़्रेमेट (अत्यधिक तेज़ प्लेबैक) के बारे में सभी जानकारी खो गया है। रंग-स्थान भी गलत दिखता है (एन्कोडर की तरफ कैमरे के डिफ़ॉल्ट का उपयोग करके एटीएम)।एंड्रॉइड मीडियाकोडेक
public class AvcEncoder {
private MediaCodec mediaCodec;
private BufferedOutputStream outputStream;
public AvcEncoder() {
File f = new File(Environment.getExternalStorageDirectory(), "Download/video_encoded.264");
touch (f);
try {
outputStream = new BufferedOutputStream(new FileOutputStream(f));
Log.i("AvcEncoder", "outputStream initialized");
} catch (Exception e){
e.printStackTrace();
}
mediaCodec = MediaCodec.createEncoderByType("video/avc");
MediaFormat mediaFormat = MediaFormat.createVideoFormat("video/avc", 320, 240);
mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 125000);
mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 15);
mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar);
mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 5);
mediaCodec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
mediaCodec.start();
}
public void close() {
try {
mediaCodec.stop();
mediaCodec.release();
outputStream.flush();
outputStream.close();
} catch (Exception e){
e.printStackTrace();
}
}
// called from Camera.setPreviewCallbackWithBuffer(...) in other class
public void offerEncoder(byte[] input) {
try {
ByteBuffer[] inputBuffers = mediaCodec.getInputBuffers();
ByteBuffer[] outputBuffers = mediaCodec.getOutputBuffers();
int inputBufferIndex = mediaCodec.dequeueInputBuffer(-1);
if (inputBufferIndex >= 0) {
ByteBuffer inputBuffer = inputBuffers[inputBufferIndex];
inputBuffer.clear();
inputBuffer.put(input);
mediaCodec.queueInputBuffer(inputBufferIndex, 0, input.length, 0, 0);
}
MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
int outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo,0);
while (outputBufferIndex >= 0) {
ByteBuffer outputBuffer = outputBuffers[outputBufferIndex];
byte[] outData = new byte[bufferInfo.size];
outputBuffer.get(outData);
outputStream.write(outData, 0, outData.length);
Log.i("AvcEncoder", outData.length + " bytes written");
mediaCodec.releaseOutputBuffer(outputBufferIndex, false);
outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 0);
}
} catch (Throwable t) {
t.printStackTrace();
}
}
एनकोडर प्रकार बदलने के लिए "वीडियो/mp4" जाहिरा तौर पर फ़्रेमरेट-समस्या का हल है, लेकिन मुख्य लक्ष्य एक स्ट्रीमिंग सेवा करना है, यह एक अच्छा समाधान नहीं है।
मुझे पता है कि मैंने एसपीएस और पीपीएस न्यूल पर विचार करते हुए कुछ एलेक्स कोड को छोड़ दिया, लेकिन मुझे उम्मीद थी कि यह आवश्यक नहीं होगा क्योंकि यह जानकारी outData
से भी आ रही थी और मुझे लगता है कि एन्कोडर इसे सही तरीके से प्रारूपित करेगा। यदि ऐसा नहीं है, तो मुझे अपनी फ़ाइल/स्ट्रीम में विभिन्न प्रकार के एनयूएल की व्यवस्था कैसे करनी चाहिए?
तो, वैध, काम कर रहे H.264 स्ट्रीम को बनाने के लिए मैं यहां क्या खो रहा हूं? और कैमरे के रंगस्थान और एन्कोडर के रंगस्थान के बीच एक मैच बनाने के लिए मुझे किन सेटिंग्स का उपयोग करना चाहिए?
मुझे एहसास है कि एंड्रॉइड/मीडियाकोडेक विषय की तुलना में यह H.264 से संबंधित प्रश्न है। या फिर भी मैं MediaCodec API का सही उपयोग नहीं कर रहा हूं?
अग्रिम धन्यवाद।
मुझे एंड्रॉइड के मीडिया प्लेयर के साथ बहुत सारे मुद्दे हैं, और यह भी कि एंड्रॉइड फोन कितने अलग हैं अलग ढंग से। क्या आपके लिए रूपांतरण सर्वर पक्ष करना संभव है? –
मैं इसी तरह की कार्यक्षमता पर काम कर रहा हूं लेकिन वर्तमान में कैमरा.एपियो.बफरबवरफ्लो एक्सेप्शन प्राप्त कर रहा हूं जब कैमरा.सेटप्रवाहवॉलबेलबैक विथबफर (...) से ऑफर एन्कोडर (...) को कॉल कर रहा है, तो क्या आप कैमरे में प्राप्त दृष्टिकोण को साझा करने में सक्षम होंगे .setPreviewCallbackWithBuffer (...)। बहुत धन्यवाद। – lucasweb
कोड java.nio.BufferOverflowException को छोड़कर ठीक लगता है जो inputBuffer.put (इनपुट) पर होता है; बयान। बाइट को buffer.capacity() भागों में विभाजित करने का प्रयास किया, MediaCodec.queueInputBuffer कॉल पर एक IllegalStateException त्रुटि के साथ समाप्त हुआ। कोई विचार यह कैसे संशोधित किया जा सकता है? –