سؤال

سألت مؤخرا سؤال حول السيطرة على حجم مقطع الصوت جافا واقترح أن أحاول JMF. نظرا لأنني أستخدم JVM قديم (1.4) ومهتم فقط في تشغيل ملفات WAV، فإن JMF كان حلا مثاليا وتبسيط التعليمات البرمجية بشكل كبير لتحميل وحجم مقاطع الصوت والتحكم فيه بشكل كبير في تطبيق My Clips.

لكنني تواجه مشكلة وقف مقاطع عند الطلب. وبعد يبدو أنها بسيطة مثل الاتصال player.stop(), ، لكن stop() يبدو أن كتلة حتى انتهى اللاعب اللعب. فيما يلي مثال رمز بسيط:

Player p = Manager.createRealizedPlayer( f.toURI().toURL() );

p.start();
System.out.println( "Player playing" );

Thread.sleep( 1000 );
System.out.println( " Clip is at time: " + p.getMediaTime().getSeconds() );

p.stop();
System.out.println( " Clip is at time: " + p.getMediaTime().getSeconds() );

هذا ينتج إخراج مثل:

Player playing
 Clip is at time: 0.8591836730000001
 Clip is at time: 3.227619047

حيث كنت أتوقع المرة الثانية أن قرأت مساويا أو موجزة فقط في وقت مبتدأ من الأول. (أو ربما تم إعادة تعيينها إلى 0 أو شيء من هذا.) لقد حاولت أيضا p.setStopTime( p.getMediaTime() ). وبعد يمنع هذا مقطع في الوقت المحدد، ولكن يلعب ثانية من التشويه قبل التوقف، وهو أمر غير مرغوب فيه.

جوجلينج حولها تجعلني أعتقد أن الآخرين لا يواجهون هذه المشكلة، وكان من الصعب العثور على خيارات. هل يمكن أن تكون هذه مشكلة التخزين المؤقت أو أنا أفتقد شيئا آخر؟ أي رؤية يمكنك تقديمها موضع تقدير كبير.


تفاصيل: أنا أستخدم (ولا يمكنني تغيير) JVM 1.4.2 مع JMF 2.1.1. كل ملفات WAV الخاصة بي هي فقط 1-10 ثانية طويلة.

هل كانت مفيدة؟

المحلول

وبالفعل كانت مشكلة التخزين المؤقت. استغرق الأمر مني بعض الوقت للعثور على ذلك لأنه عندما حاولت عرض عناصر التحكم المتوفرة مع مقتطف التعليمات البرمجية التالي، لم تكن هناك buffercontrols مدرجة:

Player p = ...
Control cs[] = p.getControls();
for ( int j = 0; j < cs.length; j++ )
  System.out.println( "  Found control: " + cs[j].getClass().getCanonicalName() );

في نهاية المطاف أنا جعلت طعنة أعمى عند الحصول على suffercontrol مع هذا المقتطف وعمل:

BufferControl bc = (BufferControl) p.getControl( "javax.media.control.BufferControl" );

بعد التحقيق والضغط حول بعض أكثر تحولت أن طول المخزن المؤقت الافتراضي كان 2 ثانية. يسمح لي تقليل طول المخزن المؤقت إلى 1 ثانية بإيقاف ملفات WAV بشكل صحيح الذي كان طويلا أو أطول. مما يزيد من تقليله إلى 0.5 ثانية انتهى مما يمنحني السلوك الذي كنت أسعى فيه أصلا إلى جميع ملفات الإدخال الخاصة بي.

دون النظر إلى مصدر JMF، أفترض أنني كنت أركض فقط في مشكلة حيث تم قراءة الصوت ولعبها في قطعتين الثانية (2 ثواني كونها طول المخزن المؤقت.) وأن تلك القطع يجب أن تنتهي من اللعب - لأي سبب - قبل أن يتم إيقافه. قد لا يؤدي تقليلها إلى 0.5 ثانية بالفعل تحديد المشكلة (إذا استمرت الأصوات بعد أن تخبرها بعد أن تتوقف) لكنها ستقلل على الأقل إلى الحد الأقصى على الأقل إلى نقطة عدم الملح الصحي. علاوة على ذلك، فإن جميع ملفات WAV الخاصة بي صغيرة ومحلية، لذلك يجب ألا تكون الكمون أو التراخية في التشغيل مشكلة.

في النهاية، هنا مراجعة مقتطف التعليمات البرمجية من السؤال الأصلي الذي ينتج عنه السلوك المطلوب:

Player p = Manager.createRealizedPlayer( f.toURI().toURL() );

BufferControl bc = (BufferControl) p.getControl( "javax.media.control.BufferControl" );
if ( bc != null )
  bc.setBufferLength( 500 ); // buffer length specified in milliseconds

p.start();
System.out.println( "Player playing" );

Thread.sleep( 1000 );
System.out.println( " Clip is at time: " + p.getMediaTime().getSeconds() );

p.stop();
System.out.println( " Clip is at time: " + p.getMediaTime().getSeconds() );

نصائح أخرى

كنت أواجه هذه المشكلة مع ملفات صوت قصيرة فقط، أيضا. وضع المخزن المؤقت لم يساعد. انتهى بي الأمر بإضافة صمت إلى الصوت في جرأة.

أنا أكره JMF :)

تحرير: حسنا، JMF أيضا Blocks GainControl.Setlevel () مكالمات عندما يكون لديك ملف صوتي قصير. أعتقد أن جذر المشكلة هو نفسه، JMF فقط يحظر طلبك (تعيين وحدة التخزين، توقف) حتى اكتمال الملف القصير.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top