/*
* This file is part of the FreeStreamer project,
* (C)Copyright 2011-2018 Matias Muhonen <mmu@iki.fi> 穆马帝
* See the file ''LICENSE'' for using the code.
*
* https://github.com/muhku/FreeStreamer
*/
#include "audio_stream.h"
#include "file_output.h"
#include "stream_configuration.h"
#include "http_stream.h"
#include "file_stream.h"
#include "caching_stream.h"
#include <CommonCrypto/CommonDigest.h>
#include <pthread.h>
/*
* Some servers may send an incorrect MIME type for the audio stream.
* By uncommenting the following line, relaxed checks will be
* performed for the MIME type. This allows playing more
* streams:
*/
//#define AS_RELAX_CONTENT_TYPE_CHECK 1
//#define AS_DEBUG 1
//#define AS_LOCK_DEBUG 1
#if !defined (AS_DEBUG)
#define AS_TRACE(...) do {} while (0)
#else
#define AS_TRACE(...) printf("[audio_stream.cpp:%i thread %x] ", __LINE__, pthread_mach_thread_np(pthread_self())); printf(__VA_ARGS__)
#endif
#if !defined (AS_LOCK_DEBUG)
#define AS_LOCK_TRACE(...) do {} while (0)
#else
#define AS_LOCK_TRACE(...) printf("[audio_stream.cpp:%i thread %x] ", __LINE__, pthread_mach_thread_np(pthread_self())); printf(__VA_ARGS__)
#endif
#if defined(DEBUG) || (TARGET_IPHONE_SIMULATOR)
#define AS_WARN(...) printf("[audio_stream.cpp:%i thread %x] ", __LINE__, pthread_mach_thread_np(pthread_self())); printf(__VA_ARGS__)
#else
#define AS_WARN(...) do {} while (0)
#endif
namespace astreamer {
static CFStringRef coreAudioErrorToCFString(CFStringRef basicErrorDescription, OSStatus error)
{
char str[20] = {0};
*(UInt32 *) (str + 1) = CFSwapInt32HostToBig(error);
if (isprint(str[1]) && isprint(str[2]) && isprint(str[3]) && isprint(str[4])) {
str[0] = str[5] = '\'';
str[6] = '\0';
} else {
sprintf(str, "%d", (int)error);
}
CFStringRef formattedError = CFStringCreateWithFormat(NULL,
NULL,
CFSTR("%@: error code %s"),
basicErrorDescription,
str);
return formattedError;
}
/* Create HTTP stream as Audio_Stream (this) as the delegate */
Audio_Stream::Audio_Stream() :
m_delegate(0),
m_inputStreamRunning(false),
m_audioStreamParserRunning(false),
m_initialBufferingCompleted(false),
m_discontinuity(false),
m_preloading(false),
m_audioQueueConsumedPackets(false),
m_contentLength(0),
m_defaultContentLength(0),
m_bytesReceived(0),
m_state(STOPPED),
m_inputStream(0),
m_audioQueue(0),
m_watchdogTimer(0),
m_seekTimer(0),
m_inputStreamTimer(0),
m_stateSetTimer(0),
m_audioFileStream(0),
m_audioConverter(0),
m_initializationError(noErr),
m_outputBufferSize(Stream_Configuration::configuration()->bufferSize),
m_outputBuffer(new UInt8[m_outputBufferSize]),
m_packetIdentifier(0),
m_playingPacketIdentifier(0),
m_dataOffset(0),
m_seekOffset(0),
m_bounceCount(0),
m_firstBufferingTime(0),
m_strictContentTypeChecking(Stream_Configuration::configuration()->requireStrictContentTypeChecking),
m_defaultContentType(CFSTR("audio/mpeg")),
m_contentType(NULL),
m_fileOutput(0),
m_outputFile(NULL),
m_queuedHead(0),
m_queuedTail(0),
m_playPacket(0),
m_cachedDataSize(0),
m_numPacketsToRewind(0),
m_audioDataByteCount(0),
m_audioDataPacketCount(0),
m_bitRate(0),
m_metaDataSizeInBytes(0),
m_packetDuration(0),
m_bitrateBufferIndex(0),
m_outputVolume(1.0),
m_converterRunOutOfData(false),
m_decoderShouldRun(false),
m_decoderFailed(false),
m_decoderActive(false),
m_mainRunLoop(CFRunLoopGetCurrent()),
m_decodeRunLoop(NULL)
{
memset(&m_srcFormat, 0, sizeof m_srcFormat);
memset(&m_dstFormat, 0, sizeof m_dstFormat);
Stream_Configuration *config = Stream_Configuration::configuration();
m_dstFormat.mSampleRate = config->outputSampleRate;
m_dstFormat.mFormatID = kAudioFormatLinearPCM;
m_dstFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked;
m_dstFormat.mBytesPerPacket = 4;
m_dstFormat.mFramesPerPacket = 1;
m_dstFormat.mBytesPerFrame = 4;
m_dstFormat.mChannelsPerFrame = 2;
m_dstFormat.mBitsPerChannel = 16;
if (pthread_mutex_init(&m_packetQueueMutex, NULL) != 0) {
AS_TRACE("m_packetQueueMutex init failed!\n");
}
if (pthread_mutex_init(&m_streamStateMutex, NULL) != 0) {
AS_TRACE("m_streamStateMutex init failed!\n");
}
pthread_create(&m_decodeThread, NULL, decodeLoop, this);
pthread_detach(m_decodeThread);
}
Audio_Stream::~Audio_Stream()
{
pthread_mutex_lock(&m_streamStateMutex);
m_decoderShouldRun = false;
if (m_decodeRunLoop) {
CFRunLoopStop(m_decodeRunLoop);
m_decodeRunLoop = NULL;
}
pthread_mutex_unlock(&m_streamStateMutex);
if (m_defaultContentType) {
CFRelease(m_defaultContentType);
m_defaultContentType = NULL;
}
if (m_contentType) {
CFRelease(m_contentType);
m_contentType = NULL;
}
close(true);
delete [] m_outputBuffer;
m_outputBuffer = 0;
if (m_inputStream) {
m_inputStream->m_delegate = 0;
delete m_inputStream;
m_inputStream = 0;
}
if (m_fileOutput) {
delete m_fileOutput;
m_fileOutput = 0;
}
pthread_mutex_destroy(&m_packetQueueMutex);
pthread_mutex_destroy(&m_streamStateMutex);
}
void Audio_Stream::open()
{
open(0);
}
void Audio_Stream::open(Input_Stream_Position *position)
{
if (m_inputStreamRunning || m_audioStreamParserRunning) {
AS_TRACE("%s: already running: return\n", __PRETTY_FUNCTION__);
return;
}
m_contentLength = 0;
m_bytesReceived = 0;
m_seekOffset = 0;
m_bounceCount = 0;
m_firstBufferingTime = 0;
m_bitrateBufferIndex = 0;
m_initializationError = noErr;
m_converterRunOutOfData = false;
m_audioDataPacketCount = 0;
m_bitRate = 0;
m_metaDataSizeInBytes = 0;
m_discontinuity = true;
pthread_mutex_lock(&m_streamStateMutex);
m_audioQueueConsumedPackets = false;
m_decoderShouldRun = false;
m_decoderFailed = false;
pthread_mutex_unlock(&m_streamStateMutex);
pthread_mutex_lock(&m_packetQueueMutex);
m_numPacketsToRewind = 0;
pthread_mutex_unlock(&m_packetQueueMutex);
invalidateWatchdogTimer();
Stream_Configuration *config = Stream_Configuration::configuration();
if (m_contentType) {
CFRelease(m_contentType);
m_contentType = NULL;
}
bool success = false;
if (position) {
m_initialBufferingCompleted = false;
if (m_inputStream) {
success = m_inputStream->open(*position);
}
} else {
m_initialBufferingCompleted = false;
m_packetIdentifier = 0;
if (m_inputStream) {
success = m_inputStream->open();
}
}
if (success) {
AS_TRACE("%s: HTTP stream opened, buffering...\n", __PRETTY_FUNCTION__);
m_inputStreamRunning = true;
setState(BUFFERING);
pthread_mutex_lock(&m_streamStateMutex);
if (!m_preloading && config->startupWatchdogPeriod > 0) {
pthread_mutex_unlock(&m_streamStateMutex);
createWatchdogTimer();
} else {
pthread_mutex_unlock(&m_streamStateMutex);
}
} else {
closeAndSignalError(AS_ERR_OPEN, CFSTR("Input stream open error"));
}
}
void Audio_Stream::close(bool closeParser)
{
AS_TRACE("%s: enter\n", __PRETTY_FUNCTION__);
invalidateWatchdogTimer(
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
iOS 音频队列 (110个子文件)
06e8bc7e8f74789401d50daa5cc812df158582 337B
0977b6a566c9e5424436c28512e2dd3aa00ce2 2KB
150112457ee9c10f416eb02c315f29ea801805 3KB
1b0f279f28752ec9f1a076237df92755c9629a 267B
1ddf3d455c873c0ccb0eade79835919e2c8ae5 658B
2b812731f0e82de8ac096c27f574ce5df55bf6 411B
3abd5b7ca3bc2f832ab3b00a0df2eb9d39f403 5KB
3b261ccb55b6b58bc59eb5b2b2b22b3538bbb1 2KB
3f6fd5810b9c852cf98563d82d5ed1e84ff893 804B
40a6cd0c4af2f0d93b697fbfb066793681b045 352B
410b3a6aa3bda996c9ac23585732ed95754280 386B
49e381f2da3656c1ea8f1022a280ab808772b6 1KB
4a164c918651cdd1e11dca5cc62c333f097601 65B
4ae36cd2ffd946783feacfc3747f9916b34c3d 1KB
4ecbcc87e5eedf0eee4233cd140b01c09ca693 161B
5314d1948537f0b800237c2641e0fbc475de66 193B
53537fd59c19058645c772ae9823b4f8ae495d 283B
5955e04da290b04e73e6519f498f8cfd3095d4 738B
596f7a958237131c7dc9ce175aaa1e16fca07d 743B
5de0acacc1439e002ad9151181190a85eeecf0 390B
68a0796b068ce636e813d61478fb75eaf20ba3 483B
6bca06e3d31d71278d820f0d4a5013abc7e252 3KB
71937e9d36882b6645da78a53ecaabe2ed651e 450B
76da06a8301b406667cc1e05755745022225b8 346B
7d46ecba4c75d296d3fc8b12a61605de4051f2 3KB
825d6887081415b8081db5a4d7d41f8636a56e 18KB
8c49774c9458452dd1574acd575eab82d0c385 420B
9cc26b4ab4e78e83e4c5f7c8985b6d294d826c 3KB
9f5da1e9e3d4b6dcd7f3b3d707805b59cd285c 938B
a4fdfbeb13867edc9b878f8971b3d061bb9379 1KB
aa0f35f9263ce1d0f2f99446759c3f3c9a790a 271B
acf5cd929d156f41b772e66c89aedecc3ff5d1 13KB
ae1d7dd946d9e0e6705e9536ab07d5c0eec44c 495B
b554c7c12d495192619bce4fda6c306b1755d5 3KB
be3b681122de83e380d47b840b7d0486f71f86 540B
c1441a08f1d22f4cf2f8093e7509f32d41bf24 5KB
c4b4988886db3f5190fe0ebc180a2ed5fb3d8c 245B
c78a1255c016bde922c849eef8555881c207b6 768B
c955bcc1a012e6ed307d370b7aba09f5e3fca7 7KB
c9ab1850ea2644a2735cee5f064f1d2f55fde1 3KB
cb59abedfe7d588d55016410add8a9c4bbdd8e 992B
config 137B
audio_stream.cpp 72KB
http_stream.cpp 31KB
id3_parser.cpp 18KB
audio_queue.cpp 17KB
caching_stream.cpp 12KB
file_stream.cpp 11KB
file_output.cpp 706B
stream_configuration.cpp 677B
input_stream.cpp 363B
d1929f1d28e4f33034866bf3ec31655d8596a2 5KB
d38c4d7a7cd97bedf4536af7a55cdfc35261cd 595B
d981003d68d0546c4804ac2ff47dd97c6e7921 206B
db8d65fd79fd541b2b7eba75c7378af3448f9c 254B
dc86ab424879edeb9bb4f4d0ae3b4cf0b060e5 195B
description 73B
eb73eb85f1f63e4276d779deefe0017078eae6 726B
exclude 40B
f262369b18ed5bd7dab73c7c8d1a7aba3b062e 821B
f6ffcb08e5dd2da46143a9745ca00a68b13dc6 3KB
f7286e468db0efb3af869d3872c34871e29405 4KB
fb68ef588ca098aea0367b48d2eca370317035 504B
fcc526ba37e0c1d4317dea693ce3f5688795e1 1KB
fffa021b025c0056e7ec480fd633d9e8751600 6KB
FSAudioStream.h 17KB
FSAudioController.h 8KB
audio_stream.h 7KB
Reachability.h 3KB
audio_queue.h 3KB
FSXMLHttpRequest.h 3KB
FSCheckContentTypeRequest.h 3KB
http_stream.h 3KB
caching_stream.h 2KB
stream_configuration.h 2KB
FSParsePlaylistRequest.h 2KB
file_stream.h 2KB
input_stream.h 1KB
FSPlaylistItem.h 1KB
id3_parser.h 903B
FreeStreamer.h 767B
FSParseRssPodcastFeedRequest.h 731B
file_output.h 700B
AppDelegate.h 288B
MainViewController.h 232B
HEAD 23B
index 5KB
Contents.json 2KB
Contents.json 62B
FSAudioController.m 24KB
Reachability.m 13KB
FSParsePlaylistRequest.m 10KB
FSXMLHttpRequest.m 9KB
FSCheckContentTypeRequest.m 7KB
FSParseRssPodcastFeedRequest.m 3KB
AppDelegate.m 2KB
MainViewController.m 1KB
________Tests.m 913B
FSPlaylistItem.m 504B
main.m 345B
共 110 条
- 1
- 2
资源评论
YFL_iOS
- 粉丝: 200
- 资源: 64
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功