To solve this optimization problem, we first need to define the decision variables and the objective function. Let's denote:

- $B$ as the number of advertisements on Banana Livestream,
- $D$ as the number of advertisements on Durian TV,
- $O$ as the number of advertisements on Orange Premium Video.

The objective is to maximize the total audience, which can be represented by the function: $300,000B + 10,000D + 12,000O$.

Given constraints are:
1. Cost constraint: $1500B + 300D + 500O \leq 20,000$,
2. Durian TV limit: $D \leq 15$,
3. Balance constraint for Orange Premium Video: $O \leq \frac{1}{3}(B + D + O)$,
4. Minimum advertisements on Banana Livestream: $B \geq 0.05(B + D + O)$.

To ensure that the variables are non-negative (since you can't run a negative number of ads), we also have:
- $B \geq 0$,
- $D \geq 0$,
- $O \geq 0$.

Now, let's translate these into Gurobi code in Python:

```python
from gurobipy import *

# Create a model
m = Model("Advertising_Optimization")

# Define the decision variables
B = m.addVar(vtype=GRB.INTEGER, name="Banana_Livestream")
D = m.addVar(vtype=GRB.INTEGER, name="Durian_TV")
O = m.addVar(vtype=GRB.INTEGER, name="Orange_Premium_Video")

# Define the objective function
m.setObjective(300000*B + 10000*D + 12000*O, GRB.MAXIMIZE)

# Add constraints
m.addConstr(1500*B + 300*D + 500*O <= 20000, "Budget_Constraint")
m.addConstr(D <= 15, "Durian_TV_Limit")
m.addConstr(O <= (1/3)*(B + D + O), "Orange_Balance")
m.addConstr(B >= 0.05*(B + D + O), "Banana_Minimum")

# Optimize the model
m.optimize()

# Print the results
if m.status == GRB.OPTIMAL:
    print("Optimal solution found:")
    print("Banana Livestream:", B.x)
    print("Durian TV:", D.x)
    print("Orange Premium Video:", O.x)
else:
    print("No optimal solution found")
```