C # का उपयोग करके एक स्ट्रीम से ऑडियो चलाएं


99

क्या सी # में एक तरीका है ऑडियो खेलने के लिए (उदाहरण के लिए, एमपी 3) direcly एक System.IO.Stream से। उदाहरण के लिए, वेबरेंसिटी से डेटा को अस्थायी रूप से डिस्क पर सहेजे बिना रेटुरेंड था?


NAudio के साथ समाधान

NAudio 1.3 की मदद से यह संभव है:

  1. एक URL से एक MemoryStream में एक एमपी 3 फ़ाइल लोड करें
  2. एमपी डेटा को पूरी तरह लोड होने के बाद तरंग डेटा में परिवर्तित करें
  3. का उपयोग करते हुए लहर डेटा प्लेबैक NAudio के WaveOut वर्ग

अच्छा होगा कि आप आधी भरी एमपी 3 फ़ाइल भी चला सकें, लेकिन नायडू लाइब्रेरी डिज़ाइन के कारण यह असंभव प्रतीत होता है ।

और यह वह कार्य है जो कार्य करेगा:

    public static void PlayMp3FromUrl(string url)
    {
        using (Stream ms = new MemoryStream())
        {
            using (Stream stream = WebRequest.Create(url)
                .GetResponse().GetResponseStream())
            {
                byte[] buffer = new byte[32768];
                int read;
                while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    ms.Write(buffer, 0, read);
                }
            }

            ms.Position = 0;
            using (WaveStream blockAlignedStream =
                new BlockAlignReductionStream(
                    WaveFormatConversionStream.CreatePcmStream(
                        new Mp3FileReader(ms))))
            {
                using (WaveOut waveOut = new WaveOut(WaveCallbackInfo.FunctionCallback()))
                {
                    waveOut.Init(blockAlignedStream);
                    waveOut.Play();                        
                    while (waveOut.PlaybackState == PlaybackState.Playing )                        
                    {
                        System.Threading.Thread.Sleep(100);
                    }
                }
            }
        }
    }

4
आपको यह देखकर अच्छा लगा कि यह काम कर रहा है। यह बहुत ज्यादा काम नहीं होगा, जबकि इसे ठीक से स्ट्रीमिंग के दौरान वापस खेलना होगा। मुख्य मुद्दा यह है कि Mp3FileReader वर्तमान में अग्रिम में लंबाई जानने की उम्मीद करता है। मैं
मार्क हीथ

@ मर्क हीथ क्या आपने पहले से ही समस्या को हल कर लिया था और वर्तमान एनएओडीओ संस्करण में डेमो जोड़ा या यह अभी भी आपके पाइपलाइन में है?
मार्टिन

डर नहीं अभी तक, हालांकि NAudio 1.3 में किए गए बदलावों के साथ इसे काम करने के लिए बहुत अधिक ट्विकिंग की आवश्यकता नहीं होगी।
मार्क हीथ

निशान: क्या मुझे इसे काम करने के लिए NAudio में संशोधित करने की आवश्यकता है, क्योंकि मैं सिर्फ NAudio1.3 डाउनलोड कर रहा हूं, लेकिन यह बिना किसी बदलाव के ऊपर दिए गए कोड को स्वीकार कर रहा है, लेकिन दूसरी ओर अपवाद को फेंकने पर "ACM रूपांतरण संभव नहीं" जैसा कुछ कहा जाता है।
मुबाशर

वैसे मैं निम्नलिखित अनुवाद
http://www.translate_tts

जवाबों:


56

संपादित करें: NAudio के हाल के संस्करणों में परिवर्तनों को प्रतिबिंबित करने के लिए अद्यतन किया गया उत्तर

मैंने जो लिखा है वह NAudio ओपन सोर्स .NET ऑडियो लाइब्रेरी का उपयोग करना संभव है। यह रूपांतरण करने के लिए आपके पीसी पर एक एसीएम कोडेक की तलाश करता है। वर्तमान में NAudio के साथ आपूर्ति की जाने वाली Mp3FileReader को उम्मीद है कि वह स्रोत धारा के भीतर पुन: निर्माण करने में सक्षम होगी (यह फ्रंट अप एमपी 3 फ्रेम का एक सूचकांक बनाता है), इसलिए यह नेटवर्क पर स्ट्रीमिंग के लिए उपयुक्त नहीं है। हालाँकि, आप अभी भी फ़्लो पर स्ट्रीम किए गए MP3 को डिकम्प्रेस करने के लिए NAudio में कक्षाओं MP3Frameऔर AcmMp3FrameDecompressorवर्गों का उपयोग कर सकते हैं।

मैंने अपने ब्लॉग पर एक लेख पोस्ट किया है जिसमें बताया गया है कि NAudio का उपयोग करके एमपी 3 स्ट्रीम को कैसे खेलना है । अनिवार्य रूप से आपके पास एमपी थ्री फ़्रेमों को डाउनलोड करने, उन्हें डिकॉम्प्रेस करने और उन्हें स्टोर करने में एक धागा है BufferedWaveProvider। एक अन्य धागा तो BufferedWaveProviderइनपुट के रूप में वापस खेलता है ।


3
NAudio पुस्तकालय अब कहा जाता है एक उदाहरण के आवेदन के साथ भेज रहा है Mp3StreamingDemo जो सब कुछ एक लाइव स्ट्रीम को नेटवर्क से एक एमपी 3 की आवश्यकता होगी प्रदान करना चाहिए।
मार्टिन

क्या एंड्रॉइड डिवाइस के लिए इनपुट में लाइव स्ट्रीम माइक / लाइन का उपयोग करना संभव है?
रियलटॉ

10

SoundPlayer वर्ग ऐसा कर सकते हैं। ऐसा लगता है कि आपको केवल अपनी स्ट्रीम संपत्ति को स्ट्रीम पर सेट करना है , फिर कॉल करें Play

संपादित करें
मुझे नहीं लगता कि यह एमपी 3 फ़ाइलें खेल सकता है; यह .wav तक सीमित लगता है। मुझे यकीन नहीं है कि अगर फ्रेमवर्क में ऐसा कुछ है जो सीधे एमपी 3 फ़ाइल चला सकता है। सब कुछ जो मुझे लगता है कि इसमें डब्ल्यूएमपी नियंत्रण का उपयोग करना या डायरेक्टएक्स के साथ बातचीत करना शामिल है।


1
मैं एक ऐसी .NET लाइब्रेरी खोजने की कोशिश कर रहा हूँ जो एमपी 3 एन्कोडिंग और डिकोडिंग को वर्षों से करती है, लेकिन मुझे नहीं लगता कि यह मौजूद है।
मुसिएनेसिस 13

NAudio को आपके लिए काम करना चाहिए - कम से कम डिकोडिंग के लिए (पहली पोस्ट देखें)
मार्टिन

4
जब आप आधिकारिक Microsoft वर्कअराउंड (वर्कअराउंड पर क्लिक करें): connect.microsoft.com/VisualStudio/feedback/…
Roman Starkov

SoundPlayer + memoryStream में desing द्वारा बग है। जब आप पहली बार दूसरी या तीसरी बार खेलते हैं तो यह आपके ऑडियो के मध्य में अजीब आवाज जोड़ता है।
bh_earth0

वर्कअराउंड लिंक अब काम नहीं करता है, लेकिन यह Wayback मशीन पर है: web.archive.org/web/2012072223231139/http://connect.microsoft.com/…
Forestrf

5

बास बस यही कर सकता है। बाइट से [] मेमोरी में या फ़ाइल प्रतिनिधि के माध्यम से खेलें जहां आप डेटा लौटाते हैं, ताकि आप जल्द से जल्द खेल सकें। आपके पास प्लेबैक शुरू करने के लिए पर्याप्त डेटा है।


3

मैंने विषय स्टार्टर स्रोत को थोड़ा संशोधित किया है, इसलिए यह अब पूरी तरह से लोड नहीं की गई फ़ाइल चला सकता है। यह यहाँ है (ध्यान दें, कि यह सिर्फ एक नमूना है और शुरू करने के लिए एक बिंदु है; आपको यहाँ कुछ अपवाद और त्रुटि से निपटने की आवश्यकता है):

private Stream ms = new MemoryStream();
public void PlayMp3FromUrl(string url)
{
    new Thread(delegate(object o)
    {
        var response = WebRequest.Create(url).GetResponse();
        using (var stream = response.GetResponseStream())
        {
            byte[] buffer = new byte[65536]; // 64KB chunks
            int read;
            while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
            {
                var pos = ms.Position;
                ms.Position = ms.Length;
                ms.Write(buffer, 0, read);
                ms.Position = pos;
            }
        }
    }).Start();

    // Pre-buffering some data to allow NAudio to start playing
    while (ms.Length < 65536*10)
        Thread.Sleep(1000);

    ms.Position = 0;
    using (WaveStream blockAlignedStream = new BlockAlignReductionStream(WaveFormatConversionStream.CreatePcmStream(new Mp3FileReader(ms))))
    {
        using (WaveOut waveOut = new WaveOut(WaveCallbackInfo.FunctionCallback()))
        {
            waveOut.Init(blockAlignedStream);
            waveOut.Play();
            while (waveOut.PlaybackState == PlaybackState.Playing)
            {
                System.Threading.Thread.Sleep(100);
            }
        }
    }
}

क्या आपने अपने कोड का परीक्षण किया? यदि हां, तो NAudio के किस संस्करण के साथ काम किया?
मार्टिन

इसके अलावा - आपका कोड ऐसा लगता है जैसे यह थ्रेडिंग समस्याओं के लिए काफी त्रुटि-रहित है। क्या आप वाकई जानते हैं कि आप क्या कर रहे हैं?
मार्टिन

1) हां, मैंने किया। 2) नवीनतम संस्करण के साथ। 3) यह अवधारणा का एक प्रमाण है जैसा कि मैंने अपने पिछले संदेश में कहा था।
रीवली

आप "नवीनतम संस्करण" को कैसे परिभाषित करते हैं? क्या यह संस्करण 1.3 या संशोधन 68454 पर स्रोत है?
मार्टिन

@Martin क्षमा करें, लंबे समय से यहां नहीं है। NAudio.dll मैंने इस्तेमाल किया संस्करण 1.3.8 है।
रेवली

2

मैंने इस प्रश्न का उत्तर देने के लिए Google के TTS API के साथ उपयोग की अनुमति देने के लिए प्रश्न में पोस्ट किए गए स्रोत को बदल दिया है :

bool waiting = false;
AutoResetEvent stop = new AutoResetEvent(false);
public void PlayMp3FromUrl(string url, int timeout)
{
    using (Stream ms = new MemoryStream())
    {
        using (Stream stream = WebRequest.Create(url)
            .GetResponse().GetResponseStream())
        {
            byte[] buffer = new byte[32768];
            int read;
            while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
            {
                ms.Write(buffer, 0, read);
            }
        }
        ms.Position = 0;
        using (WaveStream blockAlignedStream =
            new BlockAlignReductionStream(
                WaveFormatConversionStream.CreatePcmStream(
                    new Mp3FileReader(ms))))
        {
            using (WaveOut waveOut = new WaveOut(WaveCallbackInfo.FunctionCallback()))
            {
                waveOut.Init(blockAlignedStream);
                waveOut.PlaybackStopped += (sender, e) =>
                {
                    waveOut.Stop();
                };
                waveOut.Play();
                waiting = true;
                stop.WaitOne(timeout);
                waiting = false;
            }
        }
    }
}

के साथ आमंत्रित करें:

var playThread = new Thread(timeout => PlayMp3FromUrl("http://translate.google.com/translate_tts?q=" + HttpUtility.UrlEncode(relatedLabel.Text), (int)timeout));
playThread.IsBackground = true;
playThread.Start(10000);

इसके साथ समाप्त करें:

if (waiting)
    stop.Set();

ध्यान दें कि मैं ParameterizedThreadDelegateऊपर दिए गए कोड में उपयोग कर रहा हूं , और धागा के साथ शुरू किया गया है playThread.Start(10000);। 10000 को अधिकतम 10 सेकंड के ऑडियो के रूप में चलाया जाता है, इसलिए यदि आपकी स्ट्रीम को चलाने में अधिक समय लगता है तो इसे ट्विक करने की आवश्यकता होगी। यह आवश्यक है क्योंकि NAudio (v1.5.4.0) के वर्तमान संस्करण को यह निर्धारित करने में समस्या होती है कि स्ट्रीम कब खेल रही है। यह बाद के संस्करण में तय किया जा सकता है या शायद एक समाधान है जिसे मैंने खोजने के लिए समय नहीं लिया।


1

NAudio ने WaveOutXXXX एपीआई को लपेटा। मैंने स्रोत पर ध्यान नहीं दिया है, लेकिन अगर NAudio ने वेवऑउट वाइट () फ़ंक्शन को इस तरह से उजागर किया है जो प्रत्येक कॉल पर प्लेबैक को स्वचालित रूप से बंद नहीं करता है, तो आपको वह करना चाहिए जो आप वास्तव में चाहते हैं, जिसे खेलना शुरू करना है सभी डेटा प्राप्त करने से पहले ऑडियो स्ट्रीम।

WaveOutWrite () फ़ंक्शन का उपयोग करने से आप "आगे पढ़ सकते हैं" और आउटपुट क्यू में ऑडियो के छोटे विखंडू को डंप कर सकते हैं - विंडोज स्वचालित रूप से चंक्स को मूल रूप से बजाएगा। आपके कोड को संपीड़ित ऑडियो स्ट्रीम लेना होगा और इसे मक्खी पर WAV ऑडियो के छोटे हिस्से में बदलना होगा; यह हिस्सा वास्तव में मुश्किल होगा - मैंने कभी भी एमपी 3-टू-डब्ल्यूएवी रूपांतरण करने वाले सभी पुस्तकालयों और घटकों को एक बार में पूरी फ़ाइल में बदल दिया है। संभवतः आपका एकमात्र यथार्थवादी मौका एमपी 3 के बजाय डब्ल्यूएमए का उपयोग करना है, क्योंकि आप मल्टीमीडिया एसडीके के आसपास सरल सी # आवरण लिख सकते हैं।


1

मैंने एमपी 3 डिकोडर लाइब्रेरी को लपेटा और इसे .NET डेवलपर्स के लिए mpg123.net के रूप में उपलब्ध कराया

पीसीएम के लिए एमपी 3 फ़ाइलों को परिवर्तित करने और आईडी 3 टैग पढ़ने के लिए नमूने शामिल हैं ।


महान! मैं इस सप्ताह के अंत में इसका जायजा लेने के लिए उत्सुक हूं।
लैरी स्मिथमेयर

1

मैंने इसे किसी WebRequest से आज़माया नहीं है, लेकिन Windows Media Player ActiveX और MediaElement ( WPF से ) दोनों घटक एमपी 3 स्ट्रीम को चलाने और बफर करने में सक्षम हैं।

मैं इसे SHOUTcast धारा से आने वाले डेटा को चलाने के लिए उपयोग करता हूं और इसने बहुत अच्छा काम किया है। हालांकि, मुझे यकीन नहीं है कि यह उस परिदृश्य में काम करेगा जो आप प्रस्तावित करते हैं।


0

मैंने हमेशा इस तरह की चीजों के लिए FMOD का उपयोग किया है क्योंकि यह गैर-व्यावसायिक उपयोग के लिए मुफ्त है और अच्छी तरह से काम करता है।

उस ने कहा, मैं ख़ुशी-ख़ुशी उस चीज़ पर स्विच करूँगा जो छोटी है (FMOD ~ 300k) और ओपन-सोर्स। सुपर बोनस अंक यदि यह पूरी तरह से प्रबंधित है, तो मैं इसे अपने .exe के साथ संकलित / विलय कर सकता हूं और अन्य प्लेटफार्मों पर पोर्टेबिलिटी प्राप्त करने के लिए अतिरिक्त देखभाल नहीं करनी होगी ...

(FMOD पोर्टेबिलिटी भी करता है, लेकिन आपको स्पष्ट रूप से अलग-अलग प्लेटफ़ॉर्म के लिए अलग-अलग बायनेरी की आवश्यकता होगी)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.