ffmpeg-android Extract Audio From Digital Container Format - audio

I make program extracts audio from Digital Container Format (DCF).
I want to obtain an encoded audio file.
so, I think that I can write to file only audio stream packet.
Some DCF file work well, but some files does not work.
Please, can you help me to find a problem?
// src -- is DCF
// dest -- is going to write file
int ExtractAudio(const char src[], const char dest[]) {
av_register_all();
avcodec_register_all();
__android_log_print(ANDROID_LOG_DEBUG, "test", "dest : %s", dest);
__android_log_print(ANDROID_LOG_DEBUG, "test", "src : %s", src);
//파일을 열고 컨텍스트에 파일 형식을 불러온다.
AVFormatContext * pInputFormatContext = NULL;
int err = avformat_open_input(&pInputFormatContext, src, NULL, NULL);
if (err < 0) {
__android_log_print( ANDROID_LOG_DEBUG, "test",
"avformat_open_input Err! %d",err);
return 0;
}
FILE *destFile = fopen(dest, "wb");
FILE *srcFile = fopen(src, "rb");
if (destFile == NULL || srcFile == NULL) {
__android_log_print(ANDROID_LOG_DEBUG, "test", "fopen Err!");
__android_log_print(ANDROID_LOG_DEBUG, "test", "fopen Err!");
return 0;
}
fseek(srcFile, 0, SEEK_END);
DCFSize = ftell(srcFile);
fseek(srcFile, 0, SEEK_SET);
int nAudioStreamIdx = -1;
AVCodec *pAudioCodec = NULL;
err = av_find_stream_info(pInputFormatContext);
if (err < 0) {
__android_log_print(ANDROID_LOG_DEBUG, "test",
"av_find_stream_info Err!");
__android_log_print(ANDROID_LOG_DEBUG, "test",
"av_find_stream_info Err!");
return 0;
}
err = av_find_best_stream(pInputFormatContext, AVMEDIA_TYPE_AUDIO, -1, -1,
&pAudioCodec, NULL);
//에러처리 임시
if (err < 0) {
nAudioStreamIdx = 1;
if (err == AVERROR_STREAM_NOT_FOUND)
__android_log_print(ANDROID_LOG_DEBUG, "test",
"AVERROR_STREAM_NOT_FOUND");
if (err == AVERROR_DECODER_NOT_FOUND)
__android_log_print(ANDROID_LOG_DEBUG, "test",
"AVERROR_DECODER_NOT_FOUND ");
} else
nAudioStreamIdx = err;
AVPacket Packet;
av_init_packet(&Packet);
while (av_read_frame(pInputFormatContext, &Packet) >= 0) {
if (Packet.stream_index == nAudioStreamIdx)
{
fwrite(Packet.data, 1, Packet.size, destFile);
PaketPos = Packet.pos;
//__android_log_print(ANDROID_LOG_DEBUG, "test","Extract Progress : %d",getExtractProgress());
}
}
PaketPos = DCFSize;
return 1;
}

Related

Using RegisterHotKey with number pad values not working?

I have some constants:
constexpr int MonitorDisplay1 = 100;
constexpr int MonitorDisplay2 = 200;
constexpr int MonitorDisplay3 = 400;
constexpr int MonitorDisplay4 = 500;
constexpr int MonitorDisplay1KeyPad = 101;
constexpr int MonitorDisplay2KeyPad = 201;
constexpr int MonitorDisplay3KeyPad = 401;
constexpr int MonitorDisplay4KeyPad = 501;
I have an OnCreate where I setup the hot keys:
int CCenterCursorOnScreenDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (__super::OnCreate(lpCreateStruct) == -1)
return -1;
auto RegisterAppHotkey = [hAppWnd = GetSafeHwnd()](const int nHotKeyID, UINT vk)->bool
{
if (!::RegisterHotKey(hAppWnd, nHotKeyID, MOD_CONTROL | MOD_SHIFT, vk))
{
auto const ec = ::GetLastError();
auto const err_msg = std::format(L"RegisterHotKey failed (error: {})\n",
ec);
AfxMessageBox(err_msg.c_str());
return false;
}
return true;
};
if (m_monitors.rcMonitors.size() > 0)
{
if (!RegisterAppHotkey(MonitorDisplay1, '1'))
{
return -1;
}
if (!RegisterAppHotkey(MonitorDisplay1KeyPad, VK_NUMPAD1))
{
return -1;
}
}
if (m_monitors.rcMonitors.size() > 1)
{
if (!RegisterAppHotkey(MonitorDisplay2, '2'))
{
return -1;
}
if (!RegisterAppHotkey(MonitorDisplay2KeyPad, VK_NUMPAD2))
{
return -1;
}
}
if (m_monitors.rcMonitors.size() > 2)
{
if (!RegisterAppHotkey(MonitorDisplay3, '3'))
{
return -1;
}
if (!RegisterAppHotkey(MonitorDisplay3KeyPad, VK_NUMPAD3))
{
return -1;
}
}
if (m_monitors.rcMonitors.size() > 3)
{
if (!RegisterAppHotkey(MonitorDisplay4, '4'))
{
return -1;
}
if (!RegisterAppHotkey(MonitorDisplay4KeyPad, VK_NUMPAD4))
{
return -1;
}
}
return 0;
}
Previously I just had the 4 hotkeys for 1 / 2 / 3 and 4. They still work. I tried to add new hotkeys for for the number pad on the keyboard, but they are not working.
My OnHotKey handler:
void CCenterCursorOnScreenDlg::OnHotKey(UINT nHotKeyId, UINT nKey1, UINT nKey2)
{
if (nHotKeyId == MonitorDisplay1 || nHotKeyId == MonitorDisplay1KeyPad)
{
CenterCursorOnMonitor(0);
}
else if (nHotKeyId == MonitorDisplay2 || nHotKeyId == MonitorDisplay2KeyPad)
{
CenterCursorOnMonitor(1);
}
else if (nHotKeyId == MonitorDisplay3 || nHotKeyId == MonitorDisplay3KeyPad)
{
CenterCursorOnMonitor(2);
}
else if (nHotKeyId == MonitorDisplay4 || nHotKeyId == MonitorDisplay4KeyPad)
{
CenterCursorOnMonitor(3);
}
__super::OnHotKey(nHotKeyId, nKey1, nKey2);
}
But the number pad versions are not working. Why?
I am unregistering all 8 hotkeys, and num-lock is on. I get no warnings when registering.
This article explains List of Keys (Keyboard, Mouse and Joystick):
Because I was using CTRL + SHIFT, then the meaning of the 4 numeric keys was changing:
End
Down
Page Down
Left
It made sense to change my hotkeys to CTRL + ALT instead to avoid this issue.

texture view is not working with mediacodec for decoding below api 21

The following code is working with API 21 and above. However, when I run it on below 21, no data shows up on TextureView.
My configuration for MediaCodec:
MediaFormat format = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, 1920, 1080);
format.setByteBuffer("csd-0", ByteBuffer.allocate(100));
format.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 100000);
try {
m_codec = MediaCodec.createDecoderByType(MediaFormat.MIMETYPE_VIDEO_AVC);
m_codec.configure(format, new Surface(m_surface.getSurfaceTexture()), null, 0);
m_codec.start();
} catch (Exception e) {
e.printStackTrace();
}
The decoding part:
int inputIndex = m_codec.dequeueInputBuffer(-1);
if (inputIndex >= 0) {
ByteBuffer buffer;
MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
buffer = m_codec.getInputBuffer(inputIndex);
buffer.clear();
}
else {
buffer=m_codec.getInputBuffers()[inputIndex];
buffer.put(videoBuffer,0,info.size);
}
if (buffer != null) {
buffer.put(videoBuffer, info.offset,videoBuffer.length);
m_codec.queueInputBuffer(inputIndex, 0, videoBuffer.length, 0, 0);
}
}
MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
int outputIndex = m_codec.dequeueOutputBuffer(info, 0);
if (outputIndex >= 0) {
m_codec.releaseOutputBuffer(outputIndex, true);
}
EDIT:
I got the solution,when i removed below line, now it's working
format.setByteBuffer("csd-0", ByteBuffer.allocate(100));

TypeError: Object function Buffer(subject, encoding, offset) {

I have an error when I use my express server with buffer it crashes in this line:
authorization = Buffer.from(authorization, 'base64').toString('utf8')
The error message is:
TypeError:
Object function Buffer(subject, encoding, offset) { if (!(this instanceof Buffer)) { return new Buffer(subject, encoding, offset); } var type; if (typeof offset === 'number') { if (!Buffer.isBuffer(subject)) { throw new TypeError('First argument must be a Buffer when slicing'); } this.length = +encoding > 0 ? Math.ceil(encoding) : 0; this.parent = subject.parent ? subject.parent : subject; this.offset = offset; } else { switch (type = typeof subject) { case 'number': this.length = +subject > 0 ? Math.ceil(subject) : 0; break; case 'string': this.length = Buffer.byteLength(subject, encoding); break; case 'object': this.length = +subject.length > 0 ? Math.ceil(subject.length) : 0; break; default: throw new TypeError('First argument needs to be a number, ' + 'array or string.'); } if (this.length > Buffer.poolSize) {this.parent = new SlowBuffer(this.length); this.offset = 0; } else if (this.length > 0) { if (!pool || pool.length - pool.used < this.length) allocPool(); this.parent = pool; this.offset = pool.used; pool.used = (pool.used + this.length + 7) & ~7; } else { this.parent = zeroBuffer; this.offset = 0; } if (typeof subject !== 'number') { if (type === 'string') { this.length = this.write(subject, 0, encoding);} else if (Buffer.isBuffer(subject)) { if (subject.parent) subject.parent.copy(this.parent, this.offset, subject.offset, this.length + subject.offset); else subject.copy(this.parent, this.offset, 0, this.length); } else if (isArrayIsh(subject)) { for (var i = 0; i < this.length; i++) this.parent[i + this.offset] = subject[i]; } } } SlowBuffer.makeFastBuffer(this.parent, this, this.offset, this.length); } has no method 'from'
Your Buffer object does not contain any from function. You don't use the correct Buffer object. I guess you want to use the Node.js Buffer. Make sure that you really use it and you have an up-to-date version.

How i can destroy playerObj?

i'm trying creating engine and output Mix:
// create engine
this->res = slCreateEngine(&this->engineObject, 0, NULL, 0, NULL, NULL);
if (SL_RESULT_SUCCESS != this->res)
{
LOGI("Can't Create Engine.");
this->Free();
return;
}
this->res = (*this->engineObject)->Realize(this->engineObject, SL_BOOLEAN_FALSE);
if (SL_RESULT_SUCCESS != this->res)
{
LOGI("Can't Realize Engine.");
this->Free();
return;
}
this->res = (*this->engineObject)->GetInterface(this->engineObject, SL_IID_ENGINE, &this->engineEngine);
if (SL_RESULT_SUCCESS != this->res)
{
LOGI("Can't GetInterface Engine.");
this->Free();
return;
}
// create output mix
this->res = (*this->engineEngine)->CreateOutputMix(this->engineEngine, &this->outputmixObject, 0, NULL, NULL);
if (SL_RESULT_SUCCESS != this->res)
{
LOGI("Can't Create Output Mix.");
this->Free();
return;
}
this->res = (*this->outputmixObject)->Realize(this->outputmixObject, SL_BOOLEAN_FALSE);
if (SL_RESULT_SUCCESS != this->res)
{
LOGI("Can't Realize Output Mix.");
this->Free();
return;
}
that is successful!
Start playing mp3 stream from IceCast
(example "http://example.com/stream320"):
SLDataLocator_URI loc_uri = {SL_DATALOCATOR_URI, filename};
SLDataFormat_MIME format_mime = {SL_DATAFORMAT_MIME, (SLchar*)NULL, SL_CONTAINERTYPE_UNSPECIFIED};
SLDataSource audioSrcuri = {&loc_uri, &format_mime};
SLDataLocator_OutputMix dataLocatorOut = {SL_DATALOCATOR_OUTPUTMIX,this->outputmixObject};
SLDataSink audioSnk = {&dataLocatorOut, NULL};
const SLInterfaceID pIDs[3] = {SL_IID_PLAY, SL_IID_SEEK, SL_IID_PREFETCHSTATUS};
const SLboolean pIDsRequired[3] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
this->res = (*this->engineEngine)->CreateAudioPlayer(this->engineEngine, &this->player, &audioSrcuri, &audioSnk, 3, pIDs, pIDsRequired);
if (SL_RESULT_SUCCESS != this->res)
{
LOGI("Can't Create Audio Player.");
return;
}
this->res = (*this->player)->Realize(this->player, SL_BOOLEAN_FALSE);
if (SL_RESULT_SUCCESS != this->res)
{
LOGI("Can't Realize Audio Player.");
return;
}
this->res = (*this->player)->GetInterface(this->player, SL_IID_PLAY, &this->playerInterface);
if (SL_RESULT_SUCCESS != this->res)
{
LOGI("Can't Get Interface \"SL_IID_PLAY\" from Audio Player.");
return;
}
this->res = (*this->player)->GetInterface(this->player, SL_IID_SEEK, &this->seekInterface);
if (SL_RESULT_SUCCESS != this->res)
{
LOGI("Can't Get Interface \"SL_IID_SEEK\" from Audio Player.");
return;
}
this->res = (*this->player)->GetInterface(this->player, SL_IID_PREFETCHSTATUS, &this->prefetchInterface);
if (SL_RESULT_SUCCESS != this->res)
{
LOGI("Can't Get Interface \"SL_IID_PREFETCHSTATUS\" from Audio Player.");
return;
}
this->res = (*this->playerInterface)->SetPlayState(this->playerInterface, SL_PLAYSTATE_PAUSED);
if (SL_RESULT_SUCCESS != this->res)
{
LOGI("Can't Set Play State \"SL_PLAYSTATE_PAUSED\".");
return;
}
this->LastPlayState = SL_PLAYSTATE_PAUSED;
/*SLuint32 prefetchStatus = SL_PREFETCHSTATUS_UNDERFLOW;
while (prefetchStatus != SL_PREFETCHSTATUS_SUFFICIENTDATA)
{
LOGI("Wait until there's data to play...");
usleep(1 * 1000);
(*this->prefetchInterface)->GetPrefetchStatus(this->prefetchInterface, &prefetchStatus);
}
LOGI("Data OK.");
/* Get duration */
SLmillisecond durationInMsec = SL_TIME_UNKNOWN;
this->res = (*this->playerInterface)->GetDuration(this->playerInterface, &durationInMsec);
if (SL_RESULT_SUCCESS != this->res)
{
LOGI("Can't Get Duration.");
return;
}
if (durationInMsec == SL_TIME_UNKNOWN) {
LOGI("durationInMsec = SL_TIME_UNKNOWN");
//durationInMsec = 5000;
}
(*this->seekInterface)->SetLoop(this->seekInterface,SL_BOOLEAN_FALSE,0,SL_TIME_UNKNOWN);
filename = "http://example.com/stream320";
LogCat began print a Error msg...:
E/libOpenSLES(16432): MEDIA_BUFFERING_UPDATE -491520000% < 0
E/libOpenSLES(16432): MEDIA_BUFFERING_UPDATE -655360000% < 0
E/libOpenSLES(16432): MEDIA_BUFFERING_UPDATE -819200000% < 0
...
but stream is playing!
Ok, so i'm trying stop playing:
this->res = (*this->playerInterface)->SetPlayState(this->playerInterface, SL_PLAYSTATE_STOPPED);
if (SL_RESULT_SUCCESS != this->res)
LOGI("Can't Set Play State \"SL_PLAYSTATE_STOPPED\".");
OK! Play really is stopped, but player continues downloading stream.
???
So i'm try destroy PlayerObj:
(*this->player)->Destroy(this->player);
LogCat printed Error msg:
A//system/bin/app_process(16690): stack corruption detected: aborted
and app process terminated.
What is wrong?

CoSign API: SAPI User Management (add edit delete) example?

My app enables external signers to sign documents. —Signers who are not employees. My app will create a CoSign digital certificate for them. Then they'll sign the document, then the user should be deleted from the system. I want my app to programmatically create/delete the users.
Is there a C# example of for the SAPI User Management API?
Here's a C# example of how to get user info
namespace UMSample
{
class Program
{
private const string ADMIN_USER = "AdminUser";
private const string ADMIN_PASS = "AdminPass";
static public int AddUser(string uid)
{
SAPIUM sapium = new SAPIUMClass();
SAPICrypt sapicrypt = new SAPICrypt();
int rc;
if ((rc = sapicrypt.Init()) != 0) return 1;
if ((rc = sapium.Init()) != 0) return 1;
UMSESHandle hSes = null;
// Handle Acquire
if ((rc = sapium.HandleAcquire(out hSes)) != 0) return 1;
// Logon as Administrator
if ((rc = sapium.Logon(hSes, ADMIN_USER, "", ADMIN_PASS)) != 0)
{
sapium.HandleRelease(hSes);
return 1;
}
string UserCN = uid + " Test User";
string UserEmail = uid+"#demo.com";
string Pwd = "12345678";
if ((rc = sapium.UserAdd(
hSes,
uid,
UserCN,
UserEmail,
Pwd,
1)) != 0)
{
sapium.Logoff(hSes);
sapium.HandleRelease(hSes);
return 1;
}
/*----------------------------------*/
// An example of how to get user info
UserHandle uh;
string s1, s2, s3, s4;
int c1, c2, c3, mask = 0, updtime = 0;
SAPI_UM_ENUM_USER_CERT_STATUS_TYPE certsts;
SAPI_UM_ENUM_USER_LOGIN_STATUS loginstat;
SAPI_UM_ENUM_USER_TYPE kind = SAPI_UM_ENUM_USER_TYPE.SAPI_UM_USER_TYPE_NONE;
SAPI_UM_ENUM_USER_ENROLLMENT_STATUS enroll = SAPI_UM_ENUM_USER_ENROLLMENT_STATUS.SAPI_UM_NONE_USER_ENROLLMENT_STATUS;
SAPI_UM_ENUM_USER_ENROLLMENT_REASON enrReason;
SAPI_UM_ENUM_PENDING_REQUEST_STATUS_TYPE certrqsts;
rc = sapium.UserGetByLoginName(hSes, uid, out uh);
rc = sapium.UserInfoGetEx(hSes, uh, out s1, out s2, out s3, ref kind, ref mask, ref updtime, out s4,
out enroll, out enrReason, out loginstat, out c1, out c2, out c3, out certsts, out certrqsts);
/*----------------------------------*/
sapium.Logoff(hSes);
sapium.HandleRelease(hSes);
return 0;
}
static public int DelUser(string uid)
{
SAPIUM sapium = new SAPIUMClass();
int rc;
if ((rc = sapium.Init()) != 0) return 1;
UMSESHandle hSes = null;
if ((rc = sapium.HandleAcquire(out hSes)) != 0) return 1;
if ((rc = sapium.Logon(hSes, ADMIN_USER, "", ADMIN_PASS)) != 0)
{
sapium.HandleRelease(hSes);
return 1;
}
if ((rc = sapium.UserDelete(hSes, uid)) != 0)
{
sapium.Logoff(hSes);
sapium.HandleRelease(hSes);
return 1;
}
sapium.Logoff(hSes);
sapium.HandleRelease(hSes);
return 0;
}
static void Main(string[] args)
{
int rc;
for (int i = 0; i < 10; i++)
{
string uid = "Test" + i;
rc = AddUser(uid);
if (rc != 0) {
Console.WriteLine ("Error adding user: " + uid);
return;
}
rc = DelUser(uid);
if (rc != 0) {
Console.WriteLine ("Error deleting user: " + uid);
return;
}
Console.WriteLine("After handling user: " + uid);
}
Console.WriteLine("Press <Enter> to end");
Console.ReadKey();
}
}
}

Resources