PJSUA2 Java - How to get ongoing Call's AudioMedia - java

I'm using the Java library for PJSUA / PJSIP and i'm trying to get the AudioMedia for an answered call but its not working. I've followed the C++ documentation (no Java doc for answering calls) which has led me to the following implementation:
public void onCallMediaState(OnCallMediaStateParam param) {
CallInfo ci = this.getInfo();
for(int i = 0; i < ci.getMedia().size(); i++) {
if(ci.getMedia().get(i).getType() == pjmedia_type.PJMEDIA_TYPE_AUDIO) {
AudioMedia aum = (AudioMedia) this.getMedia(i);
}
}
}
The first part works, it finds a media in the call info with type PJMEDIA_TYPE_AUDIO, and if i check the type of this.getMedia(i) that is also PJMEDIA_TYPE_AUDIO. However when I try to cast it to type AudioMedia it fails to cast.
I assume the rest of SIP setup is working, as when I call the number, pjsua reports the incoming call and answers it, I'm just unable to get the AudioMedia to send/receive audio.
The documentation is for C++ but thus far it has been exactly the same for Java except for this part, Reference here. What am I doing wrong?

Found it!
AudioMedia has a static method typecastFromMedia(Media media) for casting to AudioMedia. I assume this is because the casting has to occur in the underlying C++ implementation so you can't just do a high-level java cast.
Working example:
public void onCallMediaState(OnCallMediaStateParam param) {
CallInfo ci = this.getInfo();
for(int i = 0; i < ci.getMedia().size(); i++) {
if(ci.getMedia().get(i).getType() == pjmedia_type.PJMEDIA_TYPE_AUDIO) {
AudioMedia aum = AudioMedia.typecastFromMedia(this.getMedia(i));
}
}
}

You can using getAudioMedia() API to get AudioMedia, my simple onCallMediaState() in
SipCall(subclass of Call class) using C++:
void SipCall::onCallMediaState(OnCallMediaStateParam &prm) {
this->callInfo = getInfo();
unsigned media_size = this->callInfo.media.size();
for (unsigned i = 0; i < media_size; i++) {
AudioMedia audioMedia = getAudioMedia(i);
// do something
//...
}
}

Related

How can I change code based on Method Argument?

public static void calculate(List<Person> data, String categoryType) {
for(int i = 0; i < categoryData.size(); i++) {
if(data.get(i).calculateCategoryOne() == firstPlace) {
...
}
}
}
If you see data.get(i).calculateCategoryOne(), the method call is for category one. The problem is that I need to copy-paste the entire code in a if-block for each category to just change this method call data.get(i).calculateCategoryTwo(), data.get(i).calculateCategoryThree(), ... data.get(i).calculateCategoryTen(),
While I can still make the logic work in this way, I feel it is redundant and not a good programming practice. Just to change one line of code, I would have to replicate the same code ten different times which will add nearly 500 lines of code.
So, my question is: Is there a way to dynamically change my method call based on the category type string argument.
I was thinking one possible way is to pass the method call in a string and convert it to a method call itself. For example, let's assume CategoryType string argument is "calculateCategoryOne()". So, data.get(i)."calculateCategoryOne()" would be recognized by the compiler as the method call itself. Is there a way to actually implement this?
I'm open to other ideas as well to reduce redundancy.
I would think using a functional interface would be appropriate here. You want different functionality depending on the categoryType, so passing in the function you want to use, rather than a String representation of it, would accomplish this.
#FunctionalInterface
public interface Calculate {
int calculate(Person data);
}
public static void calculate(List<Person> data, Calculate calculate) {
for(int i = 0; i < categoryData.size(); i++) {
if(calculate.calculate(data.get(i)) == firstPlace) {
...
}
}
}
and the call to the method would define what the calculation would be
calculate(list, p -> {
// calculation done here
});
or if this would happen frequently, you could predefine your categories once and pass those in:
Calculate categoryOne = p -> { ... };
Calculate categoryTwo = p -> { ... };
.
.
calculate(list, categoryOne);

How can I define new init in swift?

I need the code written here, I could not to paste here
https://www.geeksforgeeks.org/length-smallest-sub-string-consisting-maximum-distinct-characters/
i need it in swift
Although it's not recommended, But you can define a global constant and use it anywhere you like:
// At the top level, outside of any class or etc.
let NO_OF_CHARS = 256
Update due to question change:
C style for is deprecated in Swift (since v3 I think), you should convert the syntax to Swift like this:
/*
for (int i = 0; i < n; i++) {
}
*/
// Will be like
for i in 0...n {
}

protoc-gen-java code use Inline object prompt syntax error

describe
I want to use java to call golang grpc.I used the old golang's consumer_proto.proto to gen java code
process
protoc --java_out=/home/xxx/src/main/java custom_proto.proto
protoc --plugin=protoc-gen-grpc-java=/home/xxx/protoc-gen-grpc-java-1.7.0-linux-x86_64.exe --grpc-java_out=/home/xxx/main/java custom_proto.proto
result
I success gen my proto java file.but I find use Inline object prompt syntax error,the problem is from:
message RepGetClassBySchoolD {
RequestRClassStruct Class = 1;
}
the error is:
getClass() in xx classes in 'java.lang.Object';attempting to use incompatible return type
when I run the code,The error is:
Error:(92, 62) java: com.xxx.RepGetClassBySchoolD getClass() Unable to cover java.lang.Object's getClass()
The method to be overwritten is final
It happend at class RepGetClassBySchoolD:
public com.class100.service.usercenter.RequestRClassStruct getClass() {
return class_ == null ? com.class100.service.usercenter.RequestRClassStruct.getDefaultInstance() : class_;
}
Is there a way to make this work? Or any ideas? thanks
I solved the problem. Fix it by:
reason:
message CascadeStuGRPC {
RequestRStudentStruct requestRStudentStruct =1 ;
RequestRTeachingAssistantStruct requestRTeachingAssistantStruct = 2;
RequestRSchoolStruct SchoolLogin = 3;
RequestRClassStruct Class = 4;
}
message RepGetClassBySchoolD {
RequestRClassStruct Class = 1;
}
It's just because what I define two message with common name "Class",I have been using this in golang for a long time, and it will not go wrong,but in proto-gen-jave it,It will produce this error.
fix:
just fix it by another name like this:
message CascadeStuGRPC {
RequestRStudentStruct requestRStudentStruct =1 ;
RequestRTeachingAssistantStruct requestRTeachingAssistantStruct = 2;
RequestRSchoolStruct SchoolLogin = 3;
RequestRClassStruct ClassCa = 4;
}
message RepGetClassBySchoolD {
RequestRClassStruct ClassSch = 1;
}
it gen like this:
public com.class100.service.usercenter.RequestRClassStruct getClassCa() {
return classCa_ == null ? com.class100.service.usercenter.RequestRClassStruct.getDefaultInstance() : classCa_;}
It gen getClassCa() not getClass(),This problem is solved.

Dynamic calling of JBehave steps from inside Java

In Java I have a String object that has the text that I wish to be matched and executed by JBehave as a step. How can this be done? Can it be done?
What I am really trying to do is to have a wrapper JBehave step that instruments another arbitrary JBehave step. It does a few things before and after calling on the "inner" step.
So lets say that I already have the following
When I say Hello World
and
#When("I say $text")
public void iSay(final String text)
{
System.out.println(text);
}
I want to be able to do the following :
When I repeat 4 times I say Hello World
it will call :
#When("I repeat $count times $subStepString")
public void repeat(final int repeatCount, final String subStepString)
{
// prep code here
for (int i = 0; i < repeatCount; i++)
{
howDoIdoThisBitHere(subStepString);
}
// post process code here
}
The part that says howDoIdoThisBitHere(...) should end up having JBehave match the value of subStepString as if it was encountered in the case above. This way I can use this method to call other arbitrary things.
I'm not sure this is a great idea since the step classes shouldn't have any dependency on the core configuration (StepMatchers, Runners etc.), but is this solution kind of what you're looking for?
#When("I repeat $count times $subStepString")
public void repeat(final int repeatCount, final String subStepString)
{
// prep code here
for (int i = 0; i < repeatCount; i++)
{
StoryParser sp = configuration().storyParser();
Story s = sp.parseStory(subStepString);
StoryRunner e = configuredEmbedder().storyRunner();
e.run(configuration(), configuredEmbedder().candidateSteps(), s);
}
}

Call functions put in array

for my code in Java I need to call functions for some figures inside a number. In fact, if my number is 464, I have to call functions named assert4 and assert6. I hope that you're understanding. But if I'm right, we can't concatenate a string and a variable to have the name of a function and execute it. For example :
for (int i = 0; i < number.length(); i++) {
assert + i + (); // For example executing the function assert4
}
So I can't see how I can do it. Thanks for help !
You can do this with reflection using something like YourClass.class.getMethod(...).invoke(...). (See this question for instance.)
However, this is a bit of a code smell and I encourage you to do something like
Map<Integer, Runnable> methods = new HashMap<>();
methods.put(464, YourClass::assert464);
...
for (int i = 0; i < number.length(); i++) {
methods.get(i).run();
}
If you're on Java 7 or older, the equivalent would be
methods.put(464, new Runnable() { public void run() { assert464(); } });
You can call a method using a String name using the reflection API.
Here's some tutorials on how to get started:
http://docs.oracle.com/javase/tutorial/reflect/
http://www.ibm.com/developerworks/library/j-dyn0603/

Categories

Resources